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 * The first slave has been registered at master controller
79 * The second slave has been registered at the master controller
84 * Link from master to slave 1 has been successfully created
89 * Link from slave 1 to slave 2 has been successfully created.
94 * Peer create on slave 1 successful
96 SLAVE1_PEER_CREATE_SUCCESS,
99 * Peer create on slave 2 successful
101 SLAVE2_PEER_CREATE_SUCCESS,
104 * Peer startup on slave 1 successful
106 SLAVE1_PEER_START_SUCCESS,
109 * Peer on slave 1 successfully stopped
111 SLAVE1_PEER_STOP_SUCCESS,
114 * Peer startup on slave 2 successful
116 SLAVE2_PEER_START_SUCCESS,
119 * Peer on slave 2 successfully stopped
121 SLAVE2_PEER_STOP_SUCCESS,
124 * Peer destroy on slave 1 successful
126 SLAVE1_PEER_DESTROY_SUCCESS,
129 * Peer destory on slave 2 successful
131 SLAVE2_PEER_DESTROY_SUCCESS,
134 * Slave 3 has successfully registered
139 * Slave 3 has successfully started
144 * The configuration of slave 3 is acquired
146 SLAVE3_GET_CONFIG_SUCCESS,
149 * Slave 1 has linked to slave 3; Also marks test as success
156 * Host for running master controller
158 static struct GNUNET_TESTBED_Host *host;
161 * The master controller process
163 static struct GNUNET_TESTBED_ControllerProc *cp;
166 * Handle to master controller
168 static struct GNUNET_TESTBED_Controller *mc;
171 * Slave host for running slave controller
173 static struct GNUNET_TESTBED_Host *slave;
176 * Another slave host for running another slave controller
178 static struct GNUNET_TESTBED_Host *slave2;
183 static struct GNUNET_TESTBED_Host *slave3;
186 * Slave host registration handle
188 static struct GNUNET_TESTBED_HostRegistrationHandle *rh;
191 * Handle to global configuration
193 static struct GNUNET_CONFIGURATION_Handle *cfg;
196 * Configuration of slave 3 controller
198 static struct GNUNET_CONFIGURATION_Handle *cfg3;
203 static GNUNET_SCHEDULER_TaskIdentifier abort_task;
206 * Operation handle for linking controllers
208 static struct GNUNET_TESTBED_Operation *op;
211 * Handle to peer started at slave 1
213 static struct GNUNET_TESTBED_Peer *slave1_peer;
216 * Handle to peer started at slave 2
218 static struct GNUNET_TESTBED_Peer *slave2_peer;
226 * Global testing status
228 static enum Stage result;
235 * @param tc the task context
238 do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
240 if (GNUNET_SCHEDULER_NO_TASK != abort_task)
241 GNUNET_SCHEDULER_cancel (abort_task);
243 GNUNET_TESTBED_host_destroy (slave3);
245 GNUNET_TESTBED_host_destroy (slave2);
247 GNUNET_TESTBED_host_destroy (slave);
249 GNUNET_TESTBED_host_destroy (host);
251 GNUNET_TESTBED_controller_disconnect (mc);
253 GNUNET_CONFIGURATION_destroy (cfg);
255 GNUNET_CONFIGURATION_destroy (cfg3);
257 GNUNET_TESTBED_controller_stop (cp);
259 GNUNET_TESTBED_cancel_registration (rh);
264 * abort task to run on test timed out
267 * @param tc the task context
270 do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
272 LOG (GNUNET_ERROR_TYPE_WARNING, "Test timedout -- Aborting\n");
273 abort_task = GNUNET_SCHEDULER_NO_TASK;
274 do_shutdown (cls, tc);
285 do_abort_now (void *cls)
287 if (GNUNET_SCHEDULER_NO_TASK != abort_task)
288 GNUNET_SCHEDULER_cancel (abort_task);
289 abort_task = GNUNET_SCHEDULER_add_now (&do_abort, NULL);
294 * Task for inserting delay between tests
300 delay_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
304 case SLAVE1_PEER_START_SUCCESS:
305 op = GNUNET_TESTBED_peer_stop (slave1_peer, NULL, NULL);
306 GNUNET_assert (NULL != op);
308 case SLAVE2_PEER_START_SUCCESS:
309 op = GNUNET_TESTBED_peer_stop (slave2_peer, NULL, NULL);
310 GNUNET_assert (NULL != op);
319 * Functions of this signature are called when a peer has been successfully
322 * @param cls the closure from GNUNET_TESTBED_peer_create()
323 * @param peer the handle for the created peer; NULL on any error during
325 * @param emsg NULL if peer is not NULL; else MAY contain the error description
328 peer_create_cb (void *cls, struct GNUNET_TESTBED_Peer *peer, const char *emsg)
332 case SLAVE2_LINK_SUCCESS:
333 GNUNET_assert (NULL != peer);
334 GNUNET_assert (NULL == emsg);
335 result = SLAVE1_PEER_CREATE_SUCCESS;
337 GNUNET_TESTBED_operation_done (op);
338 op = GNUNET_TESTBED_peer_create (mc, slave2, cfg, peer_create_cb, NULL);
339 GNUNET_assert (NULL != op);
341 case SLAVE1_PEER_CREATE_SUCCESS:
342 GNUNET_assert (NULL != peer);
343 GNUNET_assert (NULL == emsg);
344 result = SLAVE2_PEER_CREATE_SUCCESS;
346 GNUNET_TESTBED_operation_done (op);
347 op = GNUNET_TESTBED_peer_start (slave1_peer, NULL, NULL);
348 GNUNET_assert (NULL != op);
357 * Checks the event if it is an operation finished event and if indicates a
358 * successfull completion of operation
360 * @param event the event information to check
363 check_operation_success (const struct GNUNET_TESTBED_EventInformation *event)
365 GNUNET_assert (NULL != event);
366 GNUNET_assert (GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type);
367 GNUNET_assert (event->details.operation_finished.operation == op);
368 GNUNET_assert (NULL == event->details.operation_finished.op_cls);
369 GNUNET_assert (NULL == event->details.operation_finished.emsg);
370 GNUNET_assert (NULL == event->details.operation_finished.generic);
375 * Callback which will be called to after a host registration succeeded or failed
377 * @param cls the host which has been registered
378 * @param emsg the error message; NULL if host registration is successful
381 registration_cont (void *cls, const char *emsg);
385 * Signature of the event handler function called by the
386 * respective event controller.
389 * @param event information about the event
392 controller_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event)
396 case SLAVE2_REGISTERED:
397 check_operation_success (event);
398 GNUNET_TESTBED_operation_done (op);
400 result = SLAVE1_LINK_SUCCESS;
401 GNUNET_assert (NULL != slave2);
402 GNUNET_assert (NULL != slave);
403 op = GNUNET_TESTBED_controller_link (NULL, mc, slave2, slave, cfg, GNUNET_YES);
404 GNUNET_assert (NULL != op);
406 case SLAVE1_LINK_SUCCESS:
407 check_operation_success (event);
408 GNUNET_TESTBED_operation_done (op);
410 result = SLAVE2_LINK_SUCCESS;
411 op = GNUNET_TESTBED_peer_create (mc, slave, cfg, peer_create_cb, NULL);
412 GNUNET_assert (NULL != op);
414 case SLAVE2_PEER_CREATE_SUCCESS:
415 GNUNET_assert (GNUNET_TESTBED_ET_PEER_START == event->type);
416 GNUNET_assert (event->details.peer_start.host == slave);
417 GNUNET_assert (event->details.peer_start.peer == slave1_peer);
418 GNUNET_TESTBED_operation_done (op);
419 result = SLAVE1_PEER_START_SUCCESS;
420 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
421 (GNUNET_TIME_UNIT_SECONDS, 1), &delay_task,
424 case SLAVE1_PEER_START_SUCCESS:
425 GNUNET_assert (GNUNET_TESTBED_ET_PEER_STOP == event->type);
426 GNUNET_assert (event->details.peer_stop.peer == slave1_peer);
427 GNUNET_TESTBED_operation_done (op);
428 result = SLAVE1_PEER_STOP_SUCCESS;
429 op = GNUNET_TESTBED_peer_start (slave2_peer, NULL, NULL);
430 GNUNET_assert (NULL != op);
432 case SLAVE1_PEER_STOP_SUCCESS:
433 GNUNET_assert (GNUNET_TESTBED_ET_PEER_START == event->type);
434 GNUNET_assert (event->details.peer_start.host == slave2);
435 GNUNET_assert (event->details.peer_start.peer == slave2_peer);
436 GNUNET_TESTBED_operation_done (op);
437 result = SLAVE2_PEER_START_SUCCESS;
438 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
439 (GNUNET_TIME_UNIT_SECONDS, 1), &delay_task,
442 case SLAVE2_PEER_START_SUCCESS:
443 GNUNET_assert (GNUNET_TESTBED_ET_PEER_STOP == event->type);
444 GNUNET_assert (event->details.peer_stop.peer == slave2_peer);
445 GNUNET_TESTBED_operation_done (op);
446 result = SLAVE2_PEER_STOP_SUCCESS;
447 op = GNUNET_TESTBED_peer_destroy (slave1_peer);
448 GNUNET_assert (NULL != op);
450 case SLAVE2_PEER_STOP_SUCCESS:
451 check_operation_success (event);
452 GNUNET_TESTBED_operation_done (op);
453 result = SLAVE1_PEER_DESTROY_SUCCESS;
454 op = GNUNET_TESTBED_peer_destroy (slave2_peer);
455 GNUNET_assert (NULL != op);
457 case SLAVE1_PEER_DESTROY_SUCCESS:
458 check_operation_success (event);
459 GNUNET_TESTBED_operation_done (op);
461 result = SLAVE2_PEER_DESTROY_SUCCESS;
462 slave3 = GNUNET_TESTBED_host_create_with_id (3, "127.0.0.1", NULL, 0);
463 rh = GNUNET_TESTBED_register_host (mc, slave3, ®istration_cont, NULL);
465 case SLAVE3_REGISTERED:
466 check_operation_success (event);
467 GNUNET_TESTBED_operation_done (op);
469 result = SLAVE3_STARTED;
470 op = GNUNET_TESTBED_get_slave_config (NULL, mc, slave3);
471 GNUNET_assert (NULL != op);
474 GNUNET_assert (NULL != event);
475 GNUNET_assert (GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type);
476 GNUNET_assert (event->details.operation_finished.operation == op);
477 GNUNET_assert (NULL == event->details.operation_finished.op_cls);
478 GNUNET_assert (NULL == event->details.operation_finished.emsg);
479 cfg3 = GNUNET_CONFIGURATION_dup (event->details.operation_finished.generic);
480 GNUNET_TESTBED_operation_done (op);
481 result = SLAVE3_GET_CONFIG_SUCCESS;
482 op = GNUNET_TESTBED_controller_link (NULL, mc, slave3, slave, cfg3, GNUNET_NO);
484 case SLAVE3_GET_CONFIG_SUCCESS:
485 result = SLAVE3_LINK_SUCCESS;
486 GNUNET_TESTBED_operation_done (op);
487 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
488 (GNUNET_TIME_UNIT_SECONDS, 3),
498 * Callback which will be called to after a host registration succeeded or failed
500 * @param cls the host which has been registered
501 * @param emsg the error message; NULL if host registration is successful
504 registration_cont (void *cls, const char *emsg)
510 GNUNET_assert (NULL == emsg);
511 GNUNET_assert (NULL != mc);
512 result = SLAVE1_REGISTERED;
513 slave2 = GNUNET_TESTBED_host_create_with_id (2, "127.0.0.1", NULL, 0);
514 GNUNET_assert (NULL != slave2);
515 rh = GNUNET_TESTBED_register_host (mc, slave2, ®istration_cont, NULL);
516 GNUNET_assert (NULL != rh);
518 case SLAVE1_REGISTERED:
519 GNUNET_assert (NULL == emsg);
520 GNUNET_assert (NULL != mc);
521 result = SLAVE2_REGISTERED;
522 GNUNET_assert (NULL != cfg);
523 op = GNUNET_TESTBED_controller_link (NULL, mc, slave, NULL, cfg, GNUNET_YES);
524 GNUNET_assert (NULL != op);
526 case SLAVE2_PEER_DESTROY_SUCCESS:
527 GNUNET_assert (NULL == emsg);
528 GNUNET_assert (NULL != mc);
529 GNUNET_assert (NULL == op);
530 result = SLAVE3_REGISTERED;
531 op = GNUNET_TESTBED_controller_link (NULL, mc, slave3, NULL, cfg, GNUNET_YES);
532 GNUNET_assert (NULL != op);
541 * Callback to signal successfull startup of the controller process
543 * @param cls the closure from GNUNET_TESTBED_controller_start()
544 * @param cfg the configuration with which the controller has been started;
545 * NULL if status is not GNUNET_OK
546 * @param status GNUNET_OK if the startup is successfull; GNUNET_SYSERR if not,
547 * GNUNET_TESTBED_controller_stop() shouldn't be called in this case
550 status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *config,
556 GNUNET_assert (GNUNET_OK == status);
558 event_mask |= (1L << GNUNET_TESTBED_ET_PEER_START);
559 event_mask |= (1L << GNUNET_TESTBED_ET_PEER_STOP);
560 event_mask |= (1L << GNUNET_TESTBED_ET_CONNECT);
561 event_mask |= (1L << GNUNET_TESTBED_ET_OPERATION_FINISHED);
562 mc = GNUNET_TESTBED_controller_connect (config, host, event_mask,
563 &controller_cb, NULL);
564 GNUNET_assert (NULL != mc);
565 result = MASTER_STARTED;
566 slave = GNUNET_TESTBED_host_create_with_id (1, "127.0.0.1", NULL, 0);
567 GNUNET_assert (NULL != slave);
568 rh = GNUNET_TESTBED_register_host (mc, slave, ®istration_cont, NULL);
569 GNUNET_assert (NULL != rh);
583 * @param args arguments passed to GNUNET_PROGRAM_run
584 * @param cfgfile the path to configuration file
585 * @param cfg the configuration file handle
588 run (void *cls, char *const *args, const char *cfgfile,
589 const struct GNUNET_CONFIGURATION_Handle *config)
591 host = GNUNET_TESTBED_host_create (NULL, NULL, 0);
592 GNUNET_assert (NULL != host);
593 cfg = GNUNET_CONFIGURATION_dup (config);
594 cp = GNUNET_TESTBED_controller_start ("127.0.0.1", host, cfg, status_cb,
597 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
598 (GNUNET_TIME_UNIT_MINUTES, 5), &do_abort,
607 main (int argc, char **argv)
611 char *const argv2[] = { "test_testbed_api_controllerlink",
612 "-c", "test_testbed_api.conf",
615 struct GNUNET_GETOPT_CommandLineOption options[] = {
616 GNUNET_GETOPT_OPTION_END
618 char *const remote_args[] = {
619 "ssh", "-o", "BatchMode=yes", "127.0.0.1", "echo", "Hello", "World", NULL
621 struct GNUNET_OS_Process *auxp;
622 enum GNUNET_OS_ProcessStatusType type;
626 GNUNET_OS_start_process_vap (GNUNET_NO, GNUNET_OS_INHERIT_STD_ALL, NULL,
627 NULL, "ssh", remote_args);
628 GNUNET_assert (NULL != auxp);
631 ret = GNUNET_OS_process_status (auxp, &type, &code);
632 GNUNET_assert (GNUNET_SYSERR != ret);
635 while (GNUNET_NO == ret);
636 (void) GNUNET_OS_process_wait (auxp);
637 GNUNET_OS_process_destroy (auxp);
640 (void) printf ("Unable to run the test as this system is not configured "
641 "to use password less SSH logins to localhost.\n"
642 "Marking test as successful\n");
647 GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
648 "test_testbed_api_controllerlink", "nohelp", options,
650 if ((GNUNET_OK != ret) || (SLAVE3_LINK_SUCCESS != result))
655 /* end of test_testbed_api_controllerlink.c */