- verboser log, faster start
[oweals/gnunet.git] / src / testbed / test_testbed_api_controllerlink.c
1 /*
2       This file is part of GNUnet
3       (C) 2008--2012 Christian Grothoff (and other contributing authors)
4
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.
9
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.
14
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.
19  */
20
21 /**
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>
25  */
26
27
28 /**
29  * The controller architecture we try to achieve in this test case:
30  *
31  *                    Master Controller
32  *                    //             \\
33  *                   //               \\
34  *         Slave Controller 1---------Slave Controller 3
35  *                  ||
36  *                  ||
37  *         Slave Controller 2
38  */
39
40 #include "platform.h"
41 #include "gnunet_util_lib.h"
42 #include "gnunet_testing_lib.h"
43 #include "gnunet_testbed_service.h"
44
45 /**
46  * Generic logging shortcut
47  */
48 #define LOG(kind,...)                           \
49   GNUNET_log (kind, __VA_ARGS__)
50
51 /**
52  * Debug logging shorthand
53  */
54 #define LOG_DEBUG(...)                          \
55   LOG(GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
56
57 /**
58  * Different stages in testing
59  */
60 enum Stage
61 {
62
63   /**
64    * Initial stage
65    */
66   INIT,
67
68   /**
69    * Master controller has started
70    */
71   MASTER_STARTED,
72
73   /**
74    * A peer has been created on master
75    */
76   MASTER_PEER_CREATE_SUCCESS,
77
78   /**
79    * Peer on master controller has been started successfully.
80    */
81   MASTER_PEER_START_SUCCESS,
82
83   /**
84    * The first slave has been registered at master controller
85    */
86   SLAVE1_REGISTERED,
87
88   /**
89    * The second slave has been registered at the master controller
90    */
91   SLAVE2_REGISTERED,
92
93   /**
94    * Link from master to slave 1 has been successfully created
95    */
96   SLAVE1_LINK_SUCCESS,
97
98   /**
99    * Peer create on slave 1 successful
100    */
101   SLAVE1_PEER_CREATE_SUCCESS,
102
103   /**
104    * Peer startup on slave 1 successful
105    */
106   SLAVE1_PEER_START_SUCCESS,
107
108   /**
109    * Link from slave 1 to slave 2 has been successfully created.
110    */
111   SLAVE2_LINK_SUCCESS,
112
113   /**
114    * Peer create on slave 2 successful
115    */
116   SLAVE2_PEER_CREATE_SUCCESS,
117
118   /**
119    * Peer on slave 1 successfully stopped
120    */
121   SLAVE1_PEER_STOP_SUCCESS,
122
123   /**
124    * Peer startup on slave 2 successful
125    */
126   SLAVE2_PEER_START_SUCCESS,
127
128   /**
129    * Try to connect peers on master and slave 2.
130    */
131   MASTER_SLAVE2_PEERS_CONNECTED,
132
133   /**
134    * Peer on slave 2 successfully stopped
135    */
136   SLAVE2_PEER_STOP_SUCCESS,
137
138   /**
139    * Peer destroy on slave 1 successful
140    */
141   SLAVE1_PEER_DESTROY_SUCCESS,
142
143   /**
144    * Peer destory on slave 2 successful
145    */
146   SLAVE2_PEER_DESTROY_SUCCESS,
147
148   /**
149    * Slave 3 has successfully registered
150    */
151   SLAVE3_REGISTERED,
152
153   /**
154    * Slave 3 has successfully started
155    */
156   SLAVE3_STARTED,
157
158   /**
159    * The configuration of slave 3 is acquired
160    */
161   SLAVE3_GET_CONFIG_SUCCESS,
162
163   /**
164    * Slave 1 has linked to slave 3;
165    */
166   SLAVE3_LINK_SUCCESS,
167
168   /**
169    * Destory master peer and mark test as success
170    */
171   SUCCESS,
172
173   /**
174    * Marks test as skipped
175    */
176   SKIP
177 };
178
179 /**
180  * Host for running master controller
181  */
182 static struct GNUNET_TESTBED_Host *host;
183
184 /**
185  * The master controller process
186  */
187 static struct GNUNET_TESTBED_ControllerProc *cp;
188
189 /**
190  * Handle to master controller
191  */
192 static struct GNUNET_TESTBED_Controller *mc;
193
194 /**
195  * Slave host for running slave controller
196  */
197 static struct GNUNET_TESTBED_Host *slave;
198
199 /**
200  * Another slave host for running another slave controller
201  */
202 static struct GNUNET_TESTBED_Host *slave2;
203
204 /**
205  * Host for slave 3
206  */
207 static struct GNUNET_TESTBED_Host *slave3;
208
209 /**
210  * Slave host registration handle
211  */
212 static struct GNUNET_TESTBED_HostRegistrationHandle *rh;
213
214 /**
215  * Handle to global configuration
216  */
217 static struct GNUNET_CONFIGURATION_Handle *cfg;
218
219 /**
220  * Configuration of slave 3 controller
221  */
222 static struct GNUNET_CONFIGURATION_Handle *cfg3;
223
224 /**
225  * Abort task
226  */
227 static GNUNET_SCHEDULER_TaskIdentifier abort_task;
228
229 /**
230  * Operation handle for linking controllers
231  */
232 static struct GNUNET_TESTBED_Operation *op;
233
234 /**
235  * Handle to peer started at slave 1
236  */
237 static struct GNUNET_TESTBED_Peer *slave1_peer;
238
239 /**
240  * Handle to peer started at slave 2
241  */
242 static struct GNUNET_TESTBED_Peer *slave2_peer;
243
244 /**
245  * Handle to a peer started at master controller
246  */
247 static struct GNUNET_TESTBED_Peer *master_peer;
248
249 /**
250  * The handle for whether a host is habitable or not
251  */
252 struct GNUNET_TESTBED_HostHabitableCheckHandle *hc_handle;
253
254 /**
255  * The task handle for the delay task
256  */
257 GNUNET_SCHEDULER_TaskIdentifier delay_task_id;
258
259 /**
260  * Event mask
261  */
262 uint64_t event_mask;
263
264 /**
265  * Global testing status
266  */
267 static enum Stage result;
268
269 /**
270  * shortcut to exit during failure
271  */
272 #define FAIL_TEST(cond) do {                                    \
273     if (!(cond)) {                                              \
274       GNUNET_break(0);                                          \
275       if (GNUNET_SCHEDULER_NO_TASK != abort_task)               \
276         GNUNET_SCHEDULER_cancel (abort_task);                   \
277       abort_task = GNUNET_SCHEDULER_NO_TASK;                    \
278       GNUNET_SCHEDULER_add_now (do_shutdown, NULL);             \
279       return;                                                   \
280     }                                                          \
281   } while (0)
282
283
284 /**
285  * Shutdown nicely
286  *
287  * @param cls NULL
288  * @param tc the task context
289  */
290 static void
291 do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
292 {
293   if (GNUNET_SCHEDULER_NO_TASK != abort_task)
294     GNUNET_SCHEDULER_cancel (abort_task);
295   if (GNUNET_SCHEDULER_NO_TASK != delay_task_id)
296   {
297     GNUNET_SCHEDULER_cancel (delay_task_id);
298     delay_task_id = GNUNET_SCHEDULER_NO_TASK;
299   }
300   if (NULL != hc_handle)
301     GNUNET_TESTBED_is_host_habitable_cancel (hc_handle);
302   if (NULL != slave3)
303     GNUNET_TESTBED_host_destroy (slave3);
304   if (NULL != slave2)
305     GNUNET_TESTBED_host_destroy (slave2);
306   if (NULL != slave)
307     GNUNET_TESTBED_host_destroy (slave);
308   if (NULL != host)
309     GNUNET_TESTBED_host_destroy (host);
310   if (NULL != mc)
311     GNUNET_TESTBED_controller_disconnect (mc);
312   if (NULL != cfg)
313     GNUNET_CONFIGURATION_destroy (cfg);
314   if (NULL != cfg3)
315     GNUNET_CONFIGURATION_destroy (cfg3);
316   if (NULL != cp)
317     GNUNET_TESTBED_controller_stop (cp);
318   if (NULL != rh)
319     GNUNET_TESTBED_cancel_registration (rh);
320 }
321
322
323 /**
324  * abort task to run on test timed out
325  *
326  * @param cls NULL
327  * @param tc the task context
328  */
329 static void
330 do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
331 {
332   LOG (GNUNET_ERROR_TYPE_WARNING, "Aborting\n");
333   abort_task = GNUNET_SCHEDULER_NO_TASK;
334   do_shutdown (cls, tc);
335 }
336
337
338 /**
339  * Calls abort now
340  *
341  * @param
342  * @return
343  */
344 static void
345 do_abort_now (void *cls)
346 {
347   if (GNUNET_SCHEDULER_NO_TASK != abort_task)
348     GNUNET_SCHEDULER_cancel (abort_task);
349   abort_task = GNUNET_SCHEDULER_add_now (&do_abort, NULL);
350 }
351
352
353 /**
354  * Task for inserting delay between tests
355  *
356  * @param
357  * @return
358  */
359 static void
360 delay_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
361 {
362   delay_task_id = GNUNET_SCHEDULER_NO_TASK;
363   switch (result)
364   {
365   case SLAVE2_PEER_CREATE_SUCCESS:
366     op = GNUNET_TESTBED_peer_stop (slave1_peer, NULL, NULL);
367     FAIL_TEST (NULL != op);
368     break;
369   case MASTER_SLAVE2_PEERS_CONNECTED:
370     op = GNUNET_TESTBED_peer_stop (slave2_peer, NULL, NULL);
371     FAIL_TEST (NULL != op);
372     break;
373   default:
374     FAIL_TEST (0);
375   }
376 }
377
378
379 /**
380  * Functions of this signature are called when a peer has been successfully
381  * created
382  *
383  * @param cls the closure from GNUNET_TESTBED_peer_create()
384  * @param peer the handle for the created peer; NULL on any error during
385  *          creation
386  * @param emsg NULL if peer is not NULL; else MAY contain the error description
387  */
388 static void
389 peer_create_cb (void *cls, struct GNUNET_TESTBED_Peer *peer, const char *emsg)
390 {
391   FAIL_TEST (NULL != peer);
392   FAIL_TEST (NULL == emsg);
393   switch (result)
394   {
395   case MASTER_STARTED:
396     result = MASTER_PEER_CREATE_SUCCESS;
397     master_peer = peer;
398     GNUNET_TESTBED_operation_done (op);
399     op = GNUNET_TESTBED_peer_start (NULL, master_peer, NULL, NULL);
400     break;
401   case SLAVE1_LINK_SUCCESS:
402     result = SLAVE1_PEER_CREATE_SUCCESS;
403     slave1_peer = peer;
404     GNUNET_TESTBED_operation_done (op);
405     op = GNUNET_TESTBED_peer_start (NULL, slave1_peer, NULL, NULL);
406     break;
407   case SLAVE2_LINK_SUCCESS:
408     result = SLAVE2_PEER_CREATE_SUCCESS;
409     slave2_peer = peer;
410     GNUNET_TESTBED_operation_done (op);
411     delay_task_id =
412         GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
413                                       (GNUNET_TIME_UNIT_SECONDS, 1),
414                                       &delay_task,
415                                       NULL);
416     break;
417   default:
418     FAIL_TEST (0);
419   }
420   FAIL_TEST (NULL != op);
421 }
422
423
424 /**
425  * Checks the event if it is an operation finished event and if indicates a
426  * successfull completion of operation
427  *
428  * @param event the event information to check
429  */
430 static void
431 check_operation_success (const struct GNUNET_TESTBED_EventInformation *event)
432 {
433   FAIL_TEST (NULL != event);
434   FAIL_TEST (GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type);
435   FAIL_TEST (event->details.operation_finished.operation == op);
436   FAIL_TEST (NULL == event->details.operation_finished.op_cls);
437   FAIL_TEST (NULL == event->details.operation_finished.emsg);
438   FAIL_TEST (NULL == event->details.operation_finished.generic);
439 }
440
441
442 /**
443  * Callback which will be called to after a host registration succeeded or failed
444  *
445  * @param cls the host which has been registered
446  * @param emsg the error message; NULL if host registration is successful
447  */
448 static void
449 registration_cont (void *cls, const char *emsg);
450
451
452 /**
453  * Signature of the event handler function called by the
454  * respective event controller.
455  *
456  * @param cls closure
457  * @param event information about the event
458  */
459 static void
460 controller_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event)
461 {
462   switch (result)
463   {
464   case SLAVE2_REGISTERED:
465     check_operation_success (event);
466     GNUNET_TESTBED_operation_done (op);
467     op = NULL;
468     result = SLAVE1_LINK_SUCCESS;
469     FAIL_TEST (NULL != slave2);
470     FAIL_TEST (NULL != slave);
471     op = GNUNET_TESTBED_peer_create (mc, slave, cfg, peer_create_cb, NULL);
472     FAIL_TEST (NULL != op);
473     break;
474   case SLAVE1_PEER_START_SUCCESS:
475     check_operation_success (event);
476     GNUNET_TESTBED_operation_done (op);
477     result = SLAVE2_LINK_SUCCESS;
478     op = GNUNET_TESTBED_peer_create (mc, slave2, cfg, peer_create_cb, NULL);
479     FAIL_TEST (NULL != op);
480     break;
481   case MASTER_PEER_CREATE_SUCCESS:
482     FAIL_TEST (GNUNET_TESTBED_ET_PEER_START == event->type);
483     FAIL_TEST (event->details.peer_start.host == host);
484     FAIL_TEST (event->details.peer_start.peer == master_peer);
485     GNUNET_TESTBED_operation_done (op);
486     result = MASTER_PEER_START_SUCCESS;
487     slave = GNUNET_TESTBED_host_create_with_id (1, "127.0.0.1", NULL, 0);
488     FAIL_TEST (NULL != slave);
489     rh = GNUNET_TESTBED_register_host (mc, slave, &registration_cont, NULL);
490     FAIL_TEST (NULL != rh);
491     break;
492   case SLAVE1_PEER_CREATE_SUCCESS:
493     FAIL_TEST (GNUNET_TESTBED_ET_PEER_START == event->type);
494     FAIL_TEST (event->details.peer_start.host == slave);
495     FAIL_TEST (event->details.peer_start.peer == slave1_peer);
496     GNUNET_TESTBED_operation_done (op);
497     result = SLAVE1_PEER_START_SUCCESS;
498     op = GNUNET_TESTBED_controller_link (NULL, mc, slave2, slave, cfg,
499                                          GNUNET_YES);
500     break;
501   case SLAVE2_PEER_CREATE_SUCCESS:
502     FAIL_TEST (GNUNET_TESTBED_ET_PEER_STOP == event->type);
503     FAIL_TEST (event->details.peer_stop.peer == slave1_peer);
504     GNUNET_TESTBED_operation_done (op);
505     result = SLAVE1_PEER_STOP_SUCCESS;
506     op = GNUNET_TESTBED_peer_start (NULL, slave2_peer, NULL, NULL);
507     FAIL_TEST (NULL != op);
508     break;
509   case SLAVE1_PEER_STOP_SUCCESS:
510     FAIL_TEST (GNUNET_TESTBED_ET_PEER_START == event->type);
511     FAIL_TEST (event->details.peer_start.host == slave2);
512     FAIL_TEST (event->details.peer_start.peer == slave2_peer);
513     GNUNET_TESTBED_operation_done (op);
514     result = SLAVE2_PEER_START_SUCCESS;
515     op = GNUNET_TESTBED_overlay_connect (mc, NULL, NULL, master_peer,
516                                          slave2_peer);
517     break;
518   case SLAVE2_PEER_START_SUCCESS:
519     FAIL_TEST (NULL != event);
520     FAIL_TEST (GNUNET_TESTBED_ET_CONNECT == event->type);
521     FAIL_TEST (event->details.peer_connect.peer1 == master_peer);
522     FAIL_TEST (event->details.peer_connect.peer2 == slave2_peer);
523     result = MASTER_SLAVE2_PEERS_CONNECTED;
524     GNUNET_TESTBED_operation_done (op);
525     op = NULL;
526     delay_task_id =
527         GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
528                                       (GNUNET_TIME_UNIT_SECONDS, 1), &delay_task,
529                                       NULL);
530     break;
531   case MASTER_SLAVE2_PEERS_CONNECTED:
532     FAIL_TEST (GNUNET_TESTBED_ET_PEER_STOP == event->type);
533     FAIL_TEST (event->details.peer_stop.peer == slave2_peer);
534     GNUNET_TESTBED_operation_done (op);
535     result = SLAVE2_PEER_STOP_SUCCESS;
536     op = GNUNET_TESTBED_peer_destroy (slave1_peer);
537     FAIL_TEST (NULL != op);
538     break;
539   case SLAVE2_PEER_STOP_SUCCESS:
540     check_operation_success (event);
541     GNUNET_TESTBED_operation_done (op);
542     result = SLAVE1_PEER_DESTROY_SUCCESS;
543     op = GNUNET_TESTBED_peer_destroy (slave2_peer);
544     FAIL_TEST (NULL != op);
545     break;
546   case SLAVE1_PEER_DESTROY_SUCCESS:
547     check_operation_success (event);
548     GNUNET_TESTBED_operation_done (op);
549     op = NULL;
550     result = SLAVE2_PEER_DESTROY_SUCCESS;
551     slave3 = GNUNET_TESTBED_host_create_with_id (3, "127.0.0.1", NULL, 0);
552     rh = GNUNET_TESTBED_register_host (mc, slave3, &registration_cont, NULL);
553     break;
554   case SLAVE3_REGISTERED:
555     check_operation_success (event);
556     GNUNET_TESTBED_operation_done (op);
557     op = NULL;
558     result = SLAVE3_STARTED;
559     op = GNUNET_TESTBED_get_slave_config (NULL, mc, slave3);
560     FAIL_TEST (NULL != op);
561     break;
562   case SLAVE3_STARTED:
563     FAIL_TEST (NULL != event);
564     FAIL_TEST (GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type);
565     FAIL_TEST (event->details.operation_finished.operation == op);
566     FAIL_TEST (NULL == event->details.operation_finished.op_cls);
567     FAIL_TEST (NULL == event->details.operation_finished.emsg);
568     cfg3 = GNUNET_CONFIGURATION_dup (event->details.operation_finished.generic);
569     GNUNET_TESTBED_operation_done (op);
570     result = SLAVE3_GET_CONFIG_SUCCESS;
571     op = GNUNET_TESTBED_controller_link (NULL, mc, slave3, slave, cfg3,
572                                          GNUNET_NO);
573     break;
574   case SLAVE3_GET_CONFIG_SUCCESS:
575     result = SLAVE3_LINK_SUCCESS;
576     GNUNET_TESTBED_operation_done (op);
577     op = GNUNET_TESTBED_peer_destroy (master_peer);
578     break;
579   case SLAVE3_LINK_SUCCESS:
580     check_operation_success (event);
581     result = SUCCESS;
582     GNUNET_TESTBED_operation_done (op);
583     op = NULL;
584     GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
585                                   (GNUNET_TIME_UNIT_SECONDS, 3), &do_shutdown,
586                                   NULL);
587     break;
588   default:
589     FAIL_TEST (0);
590   }
591 }
592
593
594 /**
595  * Callback which will be called to after a host registration succeeded or failed
596  *
597  * @param cls the host which has been registered
598  * @param emsg the error message; NULL if host registration is successful
599  */
600 static void
601 registration_cont (void *cls, const char *emsg)
602 {
603   rh = NULL;
604   switch (result)
605   {
606   case MASTER_PEER_START_SUCCESS:
607     FAIL_TEST (NULL == emsg);
608     FAIL_TEST (NULL != mc);
609     result = SLAVE1_REGISTERED;
610     slave2 = GNUNET_TESTBED_host_create_with_id (2, "127.0.0.1", NULL, 0);
611     FAIL_TEST (NULL != slave2);
612     rh = GNUNET_TESTBED_register_host (mc, slave2, &registration_cont, NULL);
613     FAIL_TEST (NULL != rh);
614     break;
615   case SLAVE1_REGISTERED:
616     FAIL_TEST (NULL == emsg);
617     FAIL_TEST (NULL != mc);
618     result = SLAVE2_REGISTERED;
619     FAIL_TEST (NULL != cfg);
620     op = GNUNET_TESTBED_controller_link (NULL, mc, slave, NULL, cfg,
621                                          GNUNET_YES);
622     FAIL_TEST (NULL != op);
623     break;
624   case SLAVE2_PEER_DESTROY_SUCCESS:
625     FAIL_TEST (NULL == emsg);
626     FAIL_TEST (NULL != mc);
627     FAIL_TEST (NULL == op);
628     result = SLAVE3_REGISTERED;
629     op = GNUNET_TESTBED_controller_link (NULL, mc, slave3, NULL, cfg,
630                                          GNUNET_YES);
631     FAIL_TEST (NULL != op);
632     break;
633   default:
634     GNUNET_break (0);
635     do_abort_now (NULL);
636   }
637 }
638
639 /**
640  * Callback to signal successfull startup of the controller process
641  *
642  * @param cls the closure from GNUNET_TESTBED_controller_start()
643  * @param cfg the configuration with which the controller has been started;
644  *          NULL if status is not GNUNET_OK
645  * @param status GNUNET_OK if the startup is successfull; GNUNET_SYSERR if not,
646  *          GNUNET_TESTBED_controller_stop() shouldn't be called in this case
647  */
648 static void
649 status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *config,
650            int status)
651 {
652   switch (result)
653   {
654   case INIT:
655     FAIL_TEST (GNUNET_OK == status);
656     event_mask = 0;
657     event_mask |= (1L << GNUNET_TESTBED_ET_PEER_START);
658     event_mask |= (1L << GNUNET_TESTBED_ET_PEER_STOP);
659     event_mask |= (1L << GNUNET_TESTBED_ET_CONNECT);
660     event_mask |= (1L << GNUNET_TESTBED_ET_OPERATION_FINISHED);
661     mc = GNUNET_TESTBED_controller_connect (config, host, event_mask,
662                                             &controller_cb, NULL);
663     FAIL_TEST (NULL != mc);
664     result = MASTER_STARTED;
665     op = GNUNET_TESTBED_peer_create (mc, host, cfg, peer_create_cb, NULL);
666     FAIL_TEST (NULL != op);
667     break;
668   default:
669     GNUNET_break (0);
670     cp = NULL;
671     do_abort_now (NULL);
672   }
673 }
674
675
676 /**
677  * Callbacks of this type are called by GNUNET_TESTBED_is_host_habitable to
678  * inform whether the given host is habitable or not. The Handle returned by
679  * GNUNET_TESTBED_is_host_habitable() is invalid after this callback is called
680  *
681  * @param cls NULL
682  * @param host the host whose status is being reported; will be NULL if the host
683  *          given to GNUNET_TESTBED_is_host_habitable() is NULL
684  * @param status GNUNET_YES if it is habitable; GNUNET_NO if not
685  */
686 static void
687 host_habitable_cb (void *cls, const struct GNUNET_TESTBED_Host *_host,
688                    int status)
689 {
690   hc_handle = NULL;
691   if (GNUNET_NO == status)
692   {
693     (void) PRINTF ("%s",
694                    "Unable to run the test as this system is not configured "
695                    "to use password less SSH logins to localhost.\n"
696                    "Skipping test\n");
697     GNUNET_SCHEDULER_cancel (abort_task);
698     abort_task = GNUNET_SCHEDULER_NO_TASK;
699     (void) GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
700     result = SKIP;
701     return;
702   }
703   cp = GNUNET_TESTBED_controller_start ("127.0.0.1", host, cfg, status_cb,
704                                         NULL);
705 }
706
707
708 /**
709  * Main run function.
710  *
711  * @param cls NULL
712  * @param args arguments passed to GNUNET_PROGRAM_run
713  * @param cfgfile the path to configuration file
714  * @param cfg the configuration file handle
715  */
716 static void
717 run (void *cls, char *const *args, const char *cfgfile,
718      const struct GNUNET_CONFIGURATION_Handle *config)
719 {
720   host = GNUNET_TESTBED_host_create (NULL, NULL, 0);
721   FAIL_TEST (NULL != host);
722   if (NULL ==
723       (hc_handle =
724        GNUNET_TESTBED_is_host_habitable (host, config, &host_habitable_cb,
725                                          NULL)))
726   {
727     GNUNET_TESTBED_host_destroy (host);
728     host = NULL;
729     (void) PRINTF ("%s",
730                    "Unable to run the test as this system is not configured "
731                    "to use password less SSH logins to localhost.\n"
732                    "Marking test as successful\n");
733     result = SKIP;
734     return;
735   }
736   cfg = GNUNET_CONFIGURATION_dup (config);
737   abort_task =
738       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
739                                     (GNUNET_TIME_UNIT_MINUTES, 5), &do_abort,
740                                     NULL);
741 }
742
743
744 /**
745  * Main function
746  */
747 int
748 main (int argc, char **argv)
749 {
750   char *const argv2[] = { "test_testbed_api_controllerlink",
751     "-c", "test_testbed_api.conf",
752     NULL
753   };
754   struct GNUNET_GETOPT_CommandLineOption options[] = {
755     GNUNET_GETOPT_OPTION_END
756   };
757   int ret;
758
759   result = INIT;
760   ret =
761       GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
762                           "test_testbed_api_controllerlink", "nohelp", options,
763                           &run, NULL);
764   if (GNUNET_OK != ret)
765     return 1;
766   switch (result)
767   {
768   case SUCCESS:
769     return 0;
770   case SKIP:
771     return 77;                  /* Mark test as skipped */
772   default:
773     return 1;
774   }
775 }
776
777 /* end of test_testbed_api_controllerlink.c */