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;
246 * The handle for whether a host is habitable or not
248 struct GNUNET_TESTBED_HostHabitableCheckHandle *hc_handle;
256 * Global testing status
258 static enum Stage result;
265 * @param tc the task context
268 do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
270 if (GNUNET_SCHEDULER_NO_TASK != abort_task)
271 GNUNET_SCHEDULER_cancel (abort_task);
272 if (NULL != hc_handle)
273 GNUNET_TESTBED_is_host_habitable_cancel (hc_handle);
275 GNUNET_TESTBED_host_destroy (slave3);
277 GNUNET_TESTBED_host_destroy (slave2);
279 GNUNET_TESTBED_host_destroy (slave);
281 GNUNET_TESTBED_host_destroy (host);
283 GNUNET_TESTBED_controller_disconnect (mc);
285 GNUNET_CONFIGURATION_destroy (cfg);
287 GNUNET_CONFIGURATION_destroy (cfg3);
289 GNUNET_TESTBED_controller_stop (cp);
291 GNUNET_TESTBED_cancel_registration (rh);
296 * abort task to run on test timed out
299 * @param tc the task context
302 do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
304 LOG (GNUNET_ERROR_TYPE_WARNING, "Test timedout -- Aborting\n");
305 abort_task = GNUNET_SCHEDULER_NO_TASK;
306 do_shutdown (cls, tc);
317 do_abort_now (void *cls)
319 if (GNUNET_SCHEDULER_NO_TASK != abort_task)
320 GNUNET_SCHEDULER_cancel (abort_task);
321 abort_task = GNUNET_SCHEDULER_add_now (&do_abort, NULL);
326 * Task for inserting delay between tests
332 delay_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
336 case SLAVE2_PEER_CREATE_SUCCESS:
337 op = GNUNET_TESTBED_peer_stop (slave1_peer, NULL, NULL);
338 GNUNET_assert (NULL != op);
340 case MASTER_SLAVE2_PEERS_CONNECTED:
341 op = GNUNET_TESTBED_peer_stop (slave2_peer, NULL, NULL);
342 GNUNET_assert (NULL != op);
351 * Functions of this signature are called when a peer has been successfully
354 * @param cls the closure from GNUNET_TESTBED_peer_create()
355 * @param peer the handle for the created peer; NULL on any error during
357 * @param emsg NULL if peer is not NULL; else MAY contain the error description
360 peer_create_cb (void *cls, struct GNUNET_TESTBED_Peer *peer, const char *emsg)
362 GNUNET_assert (NULL != peer);
363 GNUNET_assert (NULL == emsg);
367 result = MASTER_PEER_CREATE_SUCCESS;
369 GNUNET_TESTBED_operation_done (op);
370 op = GNUNET_TESTBED_peer_start (NULL, master_peer, NULL, NULL);
372 case SLAVE1_LINK_SUCCESS:
373 result = SLAVE1_PEER_CREATE_SUCCESS;
375 GNUNET_TESTBED_operation_done (op);
376 op = GNUNET_TESTBED_peer_start (NULL, slave1_peer, NULL, NULL);
378 case SLAVE2_LINK_SUCCESS:
379 result = SLAVE2_PEER_CREATE_SUCCESS;
381 GNUNET_TESTBED_operation_done (op);
382 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
383 (GNUNET_TIME_UNIT_SECONDS, 1), &delay_task,
389 GNUNET_assert (NULL != op);
394 * Checks the event if it is an operation finished event and if indicates a
395 * successfull completion of operation
397 * @param event the event information to check
400 check_operation_success (const struct GNUNET_TESTBED_EventInformation *event)
402 GNUNET_assert (NULL != event);
403 GNUNET_assert (GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type);
404 GNUNET_assert (event->details.operation_finished.operation == op);
405 GNUNET_assert (NULL == event->details.operation_finished.op_cls);
406 GNUNET_assert (NULL == event->details.operation_finished.emsg);
407 GNUNET_assert (NULL == event->details.operation_finished.generic);
412 * Callback which will be called to after a host registration succeeded or failed
414 * @param cls the host which has been registered
415 * @param emsg the error message; NULL if host registration is successful
418 registration_cont (void *cls, const char *emsg);
422 * Signature of the event handler function called by the
423 * respective event controller.
426 * @param event information about the event
429 controller_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event)
433 case SLAVE2_REGISTERED:
434 check_operation_success (event);
435 GNUNET_TESTBED_operation_done (op);
437 result = SLAVE1_LINK_SUCCESS;
438 GNUNET_assert (NULL != slave2);
439 GNUNET_assert (NULL != slave);
440 op = GNUNET_TESTBED_peer_create (mc, slave, cfg, peer_create_cb, NULL);
441 GNUNET_assert (NULL != op);
443 case SLAVE1_PEER_START_SUCCESS:
444 check_operation_success (event);
445 GNUNET_TESTBED_operation_done (op);
446 result = SLAVE2_LINK_SUCCESS;
447 op = GNUNET_TESTBED_peer_create (mc, slave2, cfg, peer_create_cb, NULL);
448 GNUNET_assert (NULL != op);
450 case MASTER_PEER_CREATE_SUCCESS:
451 GNUNET_assert (GNUNET_TESTBED_ET_PEER_START == event->type);
452 GNUNET_assert (event->details.peer_start.host == host);
453 GNUNET_assert (event->details.peer_start.peer == master_peer);
454 GNUNET_TESTBED_operation_done (op);
455 result = MASTER_PEER_START_SUCCESS;
456 slave = GNUNET_TESTBED_host_create_with_id (1, "127.0.0.1", NULL, 0);
457 GNUNET_assert (NULL != slave);
458 rh = GNUNET_TESTBED_register_host (mc, slave, ®istration_cont, NULL);
459 GNUNET_assert (NULL != rh);
461 case SLAVE1_PEER_CREATE_SUCCESS:
462 GNUNET_assert (GNUNET_TESTBED_ET_PEER_START == event->type);
463 GNUNET_assert (event->details.peer_start.host == slave);
464 GNUNET_assert (event->details.peer_start.peer == slave1_peer);
465 GNUNET_TESTBED_operation_done (op);
466 result = SLAVE1_PEER_START_SUCCESS;
467 op = GNUNET_TESTBED_controller_link (NULL, mc, slave2, slave, cfg,
470 case SLAVE2_PEER_CREATE_SUCCESS:
471 GNUNET_assert (GNUNET_TESTBED_ET_PEER_STOP == event->type);
472 GNUNET_assert (event->details.peer_stop.peer == slave1_peer);
473 GNUNET_TESTBED_operation_done (op);
474 result = SLAVE1_PEER_STOP_SUCCESS;
475 op = GNUNET_TESTBED_peer_start (NULL, slave2_peer, NULL, NULL);
476 GNUNET_assert (NULL != op);
478 case SLAVE1_PEER_STOP_SUCCESS:
479 GNUNET_assert (GNUNET_TESTBED_ET_PEER_START == event->type);
480 GNUNET_assert (event->details.peer_start.host == slave2);
481 GNUNET_assert (event->details.peer_start.peer == slave2_peer);
482 GNUNET_TESTBED_operation_done (op);
483 result = SLAVE2_PEER_START_SUCCESS;
484 op = GNUNET_TESTBED_overlay_connect (mc, NULL, NULL, master_peer,
487 case SLAVE2_PEER_START_SUCCESS:
488 GNUNET_assert (NULL != event);
489 GNUNET_assert (GNUNET_TESTBED_ET_CONNECT == event->type);
490 GNUNET_assert (event->details.peer_connect.peer1 == master_peer);
491 GNUNET_assert (event->details.peer_connect.peer2 == slave2_peer);
492 result = MASTER_SLAVE2_PEERS_CONNECTED;
493 GNUNET_TESTBED_operation_done (op);
495 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
496 (GNUNET_TIME_UNIT_SECONDS, 1), &delay_task,
499 case MASTER_SLAVE2_PEERS_CONNECTED:
500 GNUNET_assert (GNUNET_TESTBED_ET_PEER_STOP == event->type);
501 GNUNET_assert (event->details.peer_stop.peer == slave2_peer);
502 GNUNET_TESTBED_operation_done (op);
503 result = SLAVE2_PEER_STOP_SUCCESS;
504 op = GNUNET_TESTBED_peer_destroy (slave1_peer);
505 GNUNET_assert (NULL != op);
507 case SLAVE2_PEER_STOP_SUCCESS:
508 check_operation_success (event);
509 GNUNET_TESTBED_operation_done (op);
510 result = SLAVE1_PEER_DESTROY_SUCCESS;
511 op = GNUNET_TESTBED_peer_destroy (slave2_peer);
512 GNUNET_assert (NULL != op);
514 case SLAVE1_PEER_DESTROY_SUCCESS:
515 check_operation_success (event);
516 GNUNET_TESTBED_operation_done (op);
518 result = SLAVE2_PEER_DESTROY_SUCCESS;
519 slave3 = GNUNET_TESTBED_host_create_with_id (3, "127.0.0.1", NULL, 0);
520 rh = GNUNET_TESTBED_register_host (mc, slave3, ®istration_cont, NULL);
522 case SLAVE3_REGISTERED:
523 check_operation_success (event);
524 GNUNET_TESTBED_operation_done (op);
526 result = SLAVE3_STARTED;
527 op = GNUNET_TESTBED_get_slave_config (NULL, mc, slave3);
528 GNUNET_assert (NULL != op);
531 GNUNET_assert (NULL != event);
532 GNUNET_assert (GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type);
533 GNUNET_assert (event->details.operation_finished.operation == op);
534 GNUNET_assert (NULL == event->details.operation_finished.op_cls);
535 GNUNET_assert (NULL == event->details.operation_finished.emsg);
536 cfg3 = GNUNET_CONFIGURATION_dup (event->details.operation_finished.generic);
537 GNUNET_TESTBED_operation_done (op);
538 result = SLAVE3_GET_CONFIG_SUCCESS;
539 op = GNUNET_TESTBED_controller_link (NULL, mc, slave3, slave, cfg3, GNUNET_NO);
541 case SLAVE3_GET_CONFIG_SUCCESS:
542 result = SLAVE3_LINK_SUCCESS;
543 GNUNET_TESTBED_operation_done (op);
544 op = GNUNET_TESTBED_peer_destroy (master_peer);
546 case SLAVE3_LINK_SUCCESS:
547 check_operation_success (event);
549 GNUNET_TESTBED_operation_done (op);
551 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
552 (GNUNET_TIME_UNIT_SECONDS, 3),
562 * Callback which will be called to after a host registration succeeded or failed
564 * @param cls the host which has been registered
565 * @param emsg the error message; NULL if host registration is successful
568 registration_cont (void *cls, const char *emsg)
573 case MASTER_PEER_START_SUCCESS:
574 GNUNET_assert (NULL == emsg);
575 GNUNET_assert (NULL != mc);
576 result = SLAVE1_REGISTERED;
577 slave2 = GNUNET_TESTBED_host_create_with_id (2, "127.0.0.1", NULL, 0);
578 GNUNET_assert (NULL != slave2);
579 rh = GNUNET_TESTBED_register_host (mc, slave2, ®istration_cont, NULL);
580 GNUNET_assert (NULL != rh);
582 case SLAVE1_REGISTERED:
583 GNUNET_assert (NULL == emsg);
584 GNUNET_assert (NULL != mc);
585 result = SLAVE2_REGISTERED;
586 GNUNET_assert (NULL != cfg);
587 op = GNUNET_TESTBED_controller_link (NULL, mc, slave, NULL, cfg, GNUNET_YES);
588 GNUNET_assert (NULL != op);
590 case SLAVE2_PEER_DESTROY_SUCCESS:
591 GNUNET_assert (NULL == emsg);
592 GNUNET_assert (NULL != mc);
593 GNUNET_assert (NULL == op);
594 result = SLAVE3_REGISTERED;
595 op = GNUNET_TESTBED_controller_link (NULL, mc, slave3, NULL, cfg, GNUNET_YES);
596 GNUNET_assert (NULL != op);
605 * Callback to signal successfull startup of the controller process
607 * @param cls the closure from GNUNET_TESTBED_controller_start()
608 * @param cfg the configuration with which the controller has been started;
609 * NULL if status is not GNUNET_OK
610 * @param status GNUNET_OK if the startup is successfull; GNUNET_SYSERR if not,
611 * GNUNET_TESTBED_controller_stop() shouldn't be called in this case
614 status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *config,
620 GNUNET_assert (GNUNET_OK == status);
622 event_mask |= (1L << GNUNET_TESTBED_ET_PEER_START);
623 event_mask |= (1L << GNUNET_TESTBED_ET_PEER_STOP);
624 event_mask |= (1L << GNUNET_TESTBED_ET_CONNECT);
625 event_mask |= (1L << GNUNET_TESTBED_ET_OPERATION_FINISHED);
626 mc = GNUNET_TESTBED_controller_connect (config, host, event_mask,
627 &controller_cb, NULL);
628 GNUNET_assert (NULL != mc);
629 result = MASTER_STARTED;
630 op = GNUNET_TESTBED_peer_create (mc, host, cfg, peer_create_cb, NULL);
631 GNUNET_assert (NULL != op);
642 * Callbacks of this type are called by GNUNET_TESTBED_is_host_habitable to
643 * inform whether the given host is habitable or not. The Handle returned by
644 * GNUNET_TESTBED_is_host_habitable() is invalid after this callback is called
647 * @param host the host whose status is being reported; will be NULL if the host
648 * given to GNUNET_TESTBED_is_host_habitable() is NULL
649 * @param status GNUNET_YES if it is habitable; GNUNET_NO if not
652 host_habitable_cb (void *cls, const struct GNUNET_TESTBED_Host *_host, int status)
655 cp = GNUNET_TESTBED_controller_start ("127.0.0.1", host, cfg, status_cb,
664 * @param args arguments passed to GNUNET_PROGRAM_run
665 * @param cfgfile the path to configuration file
666 * @param cfg the configuration file handle
669 run (void *cls, char *const *args, const char *cfgfile,
670 const struct GNUNET_CONFIGURATION_Handle *config)
672 host = GNUNET_TESTBED_host_create (NULL, NULL, 0);
673 GNUNET_assert (NULL != host);
674 if (NULL == (hc_handle = GNUNET_TESTBED_is_host_habitable (host, config,
678 GNUNET_TESTBED_host_destroy (host);
681 "Unable to run the test as this system is not configured "
682 "to use password less SSH logins to localhost.\n"
683 "Marking test as successful\n");
687 cfg = GNUNET_CONFIGURATION_dup (config);
689 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
690 (GNUNET_TIME_UNIT_MINUTES, 5), &do_abort,
699 main (int argc, char **argv)
701 char *const argv2[] = { "test_testbed_api_controllerlink",
702 "-c", "test_testbed_api.conf",
705 struct GNUNET_GETOPT_CommandLineOption options[] = {
706 GNUNET_GETOPT_OPTION_END
712 GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
713 "test_testbed_api_controllerlink", "nohelp", options,
715 if ((GNUNET_OK != ret) || (SUCCESS != result))
720 /* end of test_testbed_api_controllerlink.c */