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/test_testbed_api_controllerlink.c
23 * @brief testcase for testing controller to subcontroller linking
24 * @author Sree Harsha Totakura <sreeharsha@totakura.in>
29 * The controller architecture we try to achieve in this test case:
34 * Slave Controller 1---------Slave Controller 3
41 #include "gnunet_util_lib.h"
42 #include "gnunet_testing_lib-new.h"
43 #include "gnunet_testbed_service.h"
46 * Generic logging shortcut
48 #define LOG(kind,...) \
49 GNUNET_log (kind, __VA_ARGS__)
52 * Debug logging shorthand
54 #define LOG_DEBUG(...) \
55 LOG(GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
58 * Different stages in testing
69 * Master controller has started
74 * A peer has been created on master
76 MASTER_PEER_CREATE_SUCCESS,
79 * Peer on master controller has been started successfully.
81 MASTER_PEER_START_SUCCESS,
84 * The first slave has been registered at master controller
89 * The second slave has been registered at the master controller
94 * Link from master to slave 1 has been successfully created
99 * Peer create on slave 1 successful
101 SLAVE1_PEER_CREATE_SUCCESS,
104 * Peer startup on slave 1 successful
106 SLAVE1_PEER_START_SUCCESS,
109 * Link from slave 1 to slave 2 has been successfully created.
114 * Peer create on slave 2 successful
116 SLAVE2_PEER_CREATE_SUCCESS,
119 * Peer on slave 1 successfully stopped
121 SLAVE1_PEER_STOP_SUCCESS,
124 * Peer startup on slave 2 successful
126 SLAVE2_PEER_START_SUCCESS,
129 * Try to connect peers on master and slave 2.
131 MASTER_SLAVE2_PEERS_CONNECTED,
134 * Peer on slave 2 successfully stopped
136 SLAVE2_PEER_STOP_SUCCESS,
139 * Peer destroy on slave 1 successful
141 SLAVE1_PEER_DESTROY_SUCCESS,
144 * Peer destory on slave 2 successful
146 SLAVE2_PEER_DESTROY_SUCCESS,
149 * Slave 3 has successfully registered
154 * Slave 3 has successfully started
159 * The configuration of slave 3 is acquired
161 SLAVE3_GET_CONFIG_SUCCESS,
164 * Slave 1 has linked to slave 3;
169 * Destory master peer and mark test as success
176 * Host for running master controller
178 static struct GNUNET_TESTBED_Host *host;
181 * The master controller process
183 static struct GNUNET_TESTBED_ControllerProc *cp;
186 * Handle to master controller
188 static struct GNUNET_TESTBED_Controller *mc;
191 * Slave host for running slave controller
193 static struct GNUNET_TESTBED_Host *slave;
196 * Another slave host for running another slave controller
198 static struct GNUNET_TESTBED_Host *slave2;
203 static struct GNUNET_TESTBED_Host *slave3;
206 * Slave host registration handle
208 static struct GNUNET_TESTBED_HostRegistrationHandle *rh;
211 * Handle to global configuration
213 static struct GNUNET_CONFIGURATION_Handle *cfg;
216 * Configuration of slave 3 controller
218 static struct GNUNET_CONFIGURATION_Handle *cfg3;
223 static GNUNET_SCHEDULER_TaskIdentifier abort_task;
226 * Operation handle for linking controllers
228 static struct GNUNET_TESTBED_Operation *op;
231 * Handle to peer started at slave 1
233 static struct GNUNET_TESTBED_Peer *slave1_peer;
236 * Handle to peer started at slave 2
238 static struct GNUNET_TESTBED_Peer *slave2_peer;
241 * Handle to a peer started at master controller
243 static struct GNUNET_TESTBED_Peer *master_peer;
251 * Global testing status
253 static enum Stage result;
260 * @param tc the task context
263 do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
265 if (GNUNET_SCHEDULER_NO_TASK != abort_task)
266 GNUNET_SCHEDULER_cancel (abort_task);
268 GNUNET_TESTBED_host_destroy (slave3);
270 GNUNET_TESTBED_host_destroy (slave2);
272 GNUNET_TESTBED_host_destroy (slave);
274 GNUNET_TESTBED_host_destroy (host);
276 GNUNET_TESTBED_controller_disconnect (mc);
278 GNUNET_CONFIGURATION_destroy (cfg);
280 GNUNET_CONFIGURATION_destroy (cfg3);
282 GNUNET_TESTBED_controller_stop (cp);
284 GNUNET_TESTBED_cancel_registration (rh);
289 * abort task to run on test timed out
292 * @param tc the task context
295 do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
297 LOG (GNUNET_ERROR_TYPE_WARNING, "Test timedout -- Aborting\n");
298 abort_task = GNUNET_SCHEDULER_NO_TASK;
299 do_shutdown (cls, tc);
310 do_abort_now (void *cls)
312 if (GNUNET_SCHEDULER_NO_TASK != abort_task)
313 GNUNET_SCHEDULER_cancel (abort_task);
314 abort_task = GNUNET_SCHEDULER_add_now (&do_abort, NULL);
319 * Task for inserting delay between tests
325 delay_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
329 case SLAVE2_PEER_CREATE_SUCCESS:
330 op = GNUNET_TESTBED_peer_stop (slave1_peer, NULL, NULL);
331 GNUNET_assert (NULL != op);
333 case MASTER_SLAVE2_PEERS_CONNECTED:
334 op = GNUNET_TESTBED_peer_stop (slave2_peer, NULL, NULL);
335 GNUNET_assert (NULL != op);
344 * Functions of this signature are called when a peer has been successfully
347 * @param cls the closure from GNUNET_TESTBED_peer_create()
348 * @param peer the handle for the created peer; NULL on any error during
350 * @param emsg NULL if peer is not NULL; else MAY contain the error description
353 peer_create_cb (void *cls, struct GNUNET_TESTBED_Peer *peer, const char *emsg)
355 GNUNET_assert (NULL != peer);
356 GNUNET_assert (NULL == emsg);
360 result = MASTER_PEER_CREATE_SUCCESS;
362 GNUNET_TESTBED_operation_done (op);
363 op = GNUNET_TESTBED_peer_start (NULL, master_peer, NULL, NULL);
365 case SLAVE1_LINK_SUCCESS:
366 result = SLAVE1_PEER_CREATE_SUCCESS;
368 GNUNET_TESTBED_operation_done (op);
369 op = GNUNET_TESTBED_peer_start (NULL, slave1_peer, NULL, NULL);
371 case SLAVE2_LINK_SUCCESS:
372 result = SLAVE2_PEER_CREATE_SUCCESS;
374 GNUNET_TESTBED_operation_done (op);
375 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
376 (GNUNET_TIME_UNIT_SECONDS, 1), &delay_task,
382 GNUNET_assert (NULL != op);
387 * Checks the event if it is an operation finished event and if indicates a
388 * successfull completion of operation
390 * @param event the event information to check
393 check_operation_success (const struct GNUNET_TESTBED_EventInformation *event)
395 GNUNET_assert (NULL != event);
396 GNUNET_assert (GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type);
397 GNUNET_assert (event->details.operation_finished.operation == op);
398 GNUNET_assert (NULL == event->details.operation_finished.op_cls);
399 GNUNET_assert (NULL == event->details.operation_finished.emsg);
400 GNUNET_assert (NULL == event->details.operation_finished.generic);
405 * Callback which will be called to after a host registration succeeded or failed
407 * @param cls the host which has been registered
408 * @param emsg the error message; NULL if host registration is successful
411 registration_cont (void *cls, const char *emsg);
415 * Signature of the event handler function called by the
416 * respective event controller.
419 * @param event information about the event
422 controller_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event)
426 case SLAVE2_REGISTERED:
427 check_operation_success (event);
428 GNUNET_TESTBED_operation_done (op);
430 result = SLAVE1_LINK_SUCCESS;
431 GNUNET_assert (NULL != slave2);
432 GNUNET_assert (NULL != slave);
433 op = GNUNET_TESTBED_peer_create (mc, slave, cfg, peer_create_cb, NULL);
434 GNUNET_assert (NULL != op);
436 case SLAVE1_PEER_START_SUCCESS:
437 check_operation_success (event);
438 GNUNET_TESTBED_operation_done (op);
439 result = SLAVE2_LINK_SUCCESS;
440 op = GNUNET_TESTBED_peer_create (mc, slave2, cfg, peer_create_cb, NULL);
441 GNUNET_assert (NULL != op);
443 case MASTER_PEER_CREATE_SUCCESS:
444 GNUNET_assert (GNUNET_TESTBED_ET_PEER_START == event->type);
445 GNUNET_assert (event->details.peer_start.host == host);
446 GNUNET_assert (event->details.peer_start.peer == master_peer);
447 GNUNET_TESTBED_operation_done (op);
448 result = MASTER_PEER_START_SUCCESS;
449 slave = GNUNET_TESTBED_host_create_with_id (1, "127.0.0.1", NULL, 0);
450 GNUNET_assert (NULL != slave);
451 rh = GNUNET_TESTBED_register_host (mc, slave, ®istration_cont, NULL);
452 GNUNET_assert (NULL != rh);
454 case SLAVE1_PEER_CREATE_SUCCESS:
455 GNUNET_assert (GNUNET_TESTBED_ET_PEER_START == event->type);
456 GNUNET_assert (event->details.peer_start.host == slave);
457 GNUNET_assert (event->details.peer_start.peer == slave1_peer);
458 GNUNET_TESTBED_operation_done (op);
459 result = SLAVE1_PEER_START_SUCCESS;
460 op = GNUNET_TESTBED_controller_link (NULL, mc, slave2, slave, cfg,
463 case SLAVE2_PEER_CREATE_SUCCESS:
464 GNUNET_assert (GNUNET_TESTBED_ET_PEER_STOP == event->type);
465 GNUNET_assert (event->details.peer_stop.peer == slave1_peer);
466 GNUNET_TESTBED_operation_done (op);
467 result = SLAVE1_PEER_STOP_SUCCESS;
468 op = GNUNET_TESTBED_peer_start (NULL, slave2_peer, NULL, NULL);
469 GNUNET_assert (NULL != op);
471 case SLAVE1_PEER_STOP_SUCCESS:
472 GNUNET_assert (GNUNET_TESTBED_ET_PEER_START == event->type);
473 GNUNET_assert (event->details.peer_start.host == slave2);
474 GNUNET_assert (event->details.peer_start.peer == slave2_peer);
475 GNUNET_TESTBED_operation_done (op);
476 result = SLAVE2_PEER_START_SUCCESS;
477 op = GNUNET_TESTBED_overlay_connect (mc, NULL, NULL, master_peer,
480 case SLAVE2_PEER_START_SUCCESS:
481 GNUNET_assert (NULL != event);
482 GNUNET_assert (GNUNET_TESTBED_ET_CONNECT == event->type);
483 GNUNET_assert (event->details.peer_connect.peer1 == master_peer);
484 GNUNET_assert (event->details.peer_connect.peer2 == slave2_peer);
485 result = MASTER_SLAVE2_PEERS_CONNECTED;
486 GNUNET_TESTBED_operation_done (op);
488 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
489 (GNUNET_TIME_UNIT_SECONDS, 1), &delay_task,
492 case MASTER_SLAVE2_PEERS_CONNECTED:
493 GNUNET_assert (GNUNET_TESTBED_ET_PEER_STOP == event->type);
494 GNUNET_assert (event->details.peer_stop.peer == slave2_peer);
495 GNUNET_TESTBED_operation_done (op);
496 result = SLAVE2_PEER_STOP_SUCCESS;
497 op = GNUNET_TESTBED_peer_destroy (slave1_peer);
498 GNUNET_assert (NULL != op);
500 case SLAVE2_PEER_STOP_SUCCESS:
501 check_operation_success (event);
502 GNUNET_TESTBED_operation_done (op);
503 result = SLAVE1_PEER_DESTROY_SUCCESS;
504 op = GNUNET_TESTBED_peer_destroy (slave2_peer);
505 GNUNET_assert (NULL != op);
507 case SLAVE1_PEER_DESTROY_SUCCESS:
508 check_operation_success (event);
509 GNUNET_TESTBED_operation_done (op);
511 result = SLAVE2_PEER_DESTROY_SUCCESS;
512 slave3 = GNUNET_TESTBED_host_create_with_id (3, "127.0.0.1", NULL, 0);
513 rh = GNUNET_TESTBED_register_host (mc, slave3, ®istration_cont, NULL);
515 case SLAVE3_REGISTERED:
516 check_operation_success (event);
517 GNUNET_TESTBED_operation_done (op);
519 result = SLAVE3_STARTED;
520 op = GNUNET_TESTBED_get_slave_config (NULL, mc, slave3);
521 GNUNET_assert (NULL != op);
524 GNUNET_assert (NULL != event);
525 GNUNET_assert (GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type);
526 GNUNET_assert (event->details.operation_finished.operation == op);
527 GNUNET_assert (NULL == event->details.operation_finished.op_cls);
528 GNUNET_assert (NULL == event->details.operation_finished.emsg);
529 cfg3 = GNUNET_CONFIGURATION_dup (event->details.operation_finished.generic);
530 GNUNET_TESTBED_operation_done (op);
531 result = SLAVE3_GET_CONFIG_SUCCESS;
532 op = GNUNET_TESTBED_controller_link (NULL, mc, slave3, slave, cfg3, GNUNET_NO);
534 case SLAVE3_GET_CONFIG_SUCCESS:
535 result = SLAVE3_LINK_SUCCESS;
536 GNUNET_TESTBED_operation_done (op);
537 op = GNUNET_TESTBED_peer_destroy (master_peer);
539 case SLAVE3_LINK_SUCCESS:
540 check_operation_success (event);
542 GNUNET_TESTBED_operation_done (op);
544 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
545 (GNUNET_TIME_UNIT_SECONDS, 3),
555 * Callback which will be called to after a host registration succeeded or failed
557 * @param cls the host which has been registered
558 * @param emsg the error message; NULL if host registration is successful
561 registration_cont (void *cls, const char *emsg)
566 case MASTER_PEER_START_SUCCESS:
567 GNUNET_assert (NULL == emsg);
568 GNUNET_assert (NULL != mc);
569 result = SLAVE1_REGISTERED;
570 slave2 = GNUNET_TESTBED_host_create_with_id (2, "127.0.0.1", NULL, 0);
571 GNUNET_assert (NULL != slave2);
572 rh = GNUNET_TESTBED_register_host (mc, slave2, ®istration_cont, NULL);
573 GNUNET_assert (NULL != rh);
575 case SLAVE1_REGISTERED:
576 GNUNET_assert (NULL == emsg);
577 GNUNET_assert (NULL != mc);
578 result = SLAVE2_REGISTERED;
579 GNUNET_assert (NULL != cfg);
580 op = GNUNET_TESTBED_controller_link (NULL, mc, slave, NULL, cfg, GNUNET_YES);
581 GNUNET_assert (NULL != op);
583 case SLAVE2_PEER_DESTROY_SUCCESS:
584 GNUNET_assert (NULL == emsg);
585 GNUNET_assert (NULL != mc);
586 GNUNET_assert (NULL == op);
587 result = SLAVE3_REGISTERED;
588 op = GNUNET_TESTBED_controller_link (NULL, mc, slave3, NULL, cfg, GNUNET_YES);
589 GNUNET_assert (NULL != op);
598 * Callback to signal successfull startup of the controller process
600 * @param cls the closure from GNUNET_TESTBED_controller_start()
601 * @param cfg the configuration with which the controller has been started;
602 * NULL if status is not GNUNET_OK
603 * @param status GNUNET_OK if the startup is successfull; GNUNET_SYSERR if not,
604 * GNUNET_TESTBED_controller_stop() shouldn't be called in this case
607 status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *config,
613 GNUNET_assert (GNUNET_OK == status);
615 event_mask |= (1L << GNUNET_TESTBED_ET_PEER_START);
616 event_mask |= (1L << GNUNET_TESTBED_ET_PEER_STOP);
617 event_mask |= (1L << GNUNET_TESTBED_ET_CONNECT);
618 event_mask |= (1L << GNUNET_TESTBED_ET_OPERATION_FINISHED);
619 mc = GNUNET_TESTBED_controller_connect (config, host, event_mask,
620 &controller_cb, NULL);
621 GNUNET_assert (NULL != mc);
622 result = MASTER_STARTED;
623 op = GNUNET_TESTBED_peer_create (mc, host, cfg, peer_create_cb, NULL);
624 GNUNET_assert (NULL != op);
638 * @param args arguments passed to GNUNET_PROGRAM_run
639 * @param cfgfile the path to configuration file
640 * @param cfg the configuration file handle
643 run (void *cls, char *const *args, const char *cfgfile,
644 const struct GNUNET_CONFIGURATION_Handle *config)
646 host = GNUNET_TESTBED_host_create (NULL, NULL, 0);
647 GNUNET_assert (NULL != host);
648 if (GNUNET_YES != GNUNET_TESTBED_is_host_habitable (host, config))
650 GNUNET_TESTBED_host_destroy (host);
653 "Unable to run the test as this system is not configured "
654 "to use password less SSH logins to localhost.\n"
655 "Marking test as successful\n");
659 cfg = GNUNET_CONFIGURATION_dup (config);
660 cp = GNUNET_TESTBED_controller_start ("127.0.0.1", host, cfg, status_cb,
663 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
664 (GNUNET_TIME_UNIT_MINUTES, 5), &do_abort,
673 main (int argc, char **argv)
675 char *const argv2[] = { "test_testbed_api_controllerlink",
676 "-c", "test_testbed_api.conf",
679 struct GNUNET_GETOPT_CommandLineOption options[] = {
680 GNUNET_GETOPT_OPTION_END
686 GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
687 "test_testbed_api_controllerlink", "nohelp", options,
689 if ((GNUNET_OK != ret) || (SUCCESS != result))
694 /* end of test_testbed_api_controllerlink.c */