10235b88450a859f470086182bedefeb4a41d0af
[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  * Event mask
256  */
257 uint64_t event_mask;
258
259 /**
260  * Global testing status
261  */
262 static enum Stage result;
263
264
265 /**
266  * Shutdown nicely
267  *
268  * @param cls NULL
269  * @param tc the task context
270  */
271 static void
272 do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
273 {
274   if (GNUNET_SCHEDULER_NO_TASK != abort_task)
275     GNUNET_SCHEDULER_cancel (abort_task);
276   if (NULL != hc_handle)
277     GNUNET_TESTBED_is_host_habitable_cancel (hc_handle);
278   if (NULL != slave3)
279     GNUNET_TESTBED_host_destroy (slave3);
280   if (NULL != slave2)
281     GNUNET_TESTBED_host_destroy (slave2);
282   if (NULL != slave)
283     GNUNET_TESTBED_host_destroy (slave);
284   if (NULL != host)
285     GNUNET_TESTBED_host_destroy (host);
286   if (NULL != mc)
287     GNUNET_TESTBED_controller_disconnect (mc);
288   if (NULL != cfg)
289     GNUNET_CONFIGURATION_destroy (cfg);
290   if (NULL != cfg3)
291     GNUNET_CONFIGURATION_destroy (cfg3);
292   if (NULL != cp)
293     GNUNET_TESTBED_controller_stop (cp);
294   if (NULL != rh)
295     GNUNET_TESTBED_cancel_registration (rh);
296 }
297
298
299 /**
300  * abort task to run on test timed out
301  *
302  * @param cls NULL
303  * @param tc the task context
304  */
305 static void
306 do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
307 {
308   LOG (GNUNET_ERROR_TYPE_WARNING, "Test timedout -- Aborting\n");
309   abort_task = GNUNET_SCHEDULER_NO_TASK;
310   do_shutdown (cls, tc);
311 }
312
313
314 /**
315  * Calls abort now
316  *
317  * @param 
318  * @return 
319  */
320 static void
321 do_abort_now (void *cls)
322 {
323   if (GNUNET_SCHEDULER_NO_TASK != abort_task)
324     GNUNET_SCHEDULER_cancel (abort_task);
325   abort_task = GNUNET_SCHEDULER_add_now (&do_abort, NULL);
326 }
327
328
329 /**
330  * Task for inserting delay between tests
331  *
332  * @param
333  * @return
334  */
335 static void
336 delay_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
337 {
338   switch (result)
339   {
340   case SLAVE2_PEER_CREATE_SUCCESS:
341     op = GNUNET_TESTBED_peer_stop (slave1_peer, NULL, NULL);
342     GNUNET_assert (NULL != op);
343     break;
344   case MASTER_SLAVE2_PEERS_CONNECTED:
345     op = GNUNET_TESTBED_peer_stop (slave2_peer, NULL, NULL);
346     GNUNET_assert (NULL != op);
347     break;
348   default:
349     GNUNET_assert (0);
350   }
351 }
352
353
354 /**
355  * Functions of this signature are called when a peer has been successfully
356  * created
357  *
358  * @param cls the closure from GNUNET_TESTBED_peer_create()
359  * @param peer the handle for the created peer; NULL on any error during
360  *          creation
361  * @param emsg NULL if peer is not NULL; else MAY contain the error description
362  */
363 static void
364 peer_create_cb (void *cls, struct GNUNET_TESTBED_Peer *peer, const char *emsg)
365 {
366   GNUNET_assert (NULL != peer);
367   GNUNET_assert (NULL == emsg);
368   switch (result)
369   {
370   case MASTER_STARTED:
371     result = MASTER_PEER_CREATE_SUCCESS;
372     master_peer = peer;
373     GNUNET_TESTBED_operation_done (op);
374     op = GNUNET_TESTBED_peer_start (NULL, master_peer, NULL, NULL);
375     break;
376   case SLAVE1_LINK_SUCCESS:
377     result = SLAVE1_PEER_CREATE_SUCCESS;
378     slave1_peer = peer;
379     GNUNET_TESTBED_operation_done (op);   
380     op = GNUNET_TESTBED_peer_start (NULL, slave1_peer, NULL, NULL);
381     break;
382   case SLAVE2_LINK_SUCCESS:
383     result = SLAVE2_PEER_CREATE_SUCCESS;
384     slave2_peer = peer;
385     GNUNET_TESTBED_operation_done (op);
386     GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
387                                   (GNUNET_TIME_UNIT_SECONDS, 1), &delay_task,
388                                   NULL);
389     break;
390   default:
391     GNUNET_assert (0);
392   }
393   GNUNET_assert (NULL != op);
394 }
395
396
397 /**
398  * Checks the event if it is an operation finished event and if indicates a
399  * successfull completion of operation
400  *
401  * @param event the event information to check
402  */
403 static void
404 check_operation_success (const struct GNUNET_TESTBED_EventInformation *event)
405 {
406   GNUNET_assert (NULL != event);
407   GNUNET_assert (GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type);
408   GNUNET_assert (event->details.operation_finished.operation == op);
409   GNUNET_assert (NULL == event->details.operation_finished.op_cls);
410   GNUNET_assert (NULL == event->details.operation_finished.emsg);
411   GNUNET_assert (NULL == event->details.operation_finished.generic);
412 }
413
414
415 /**
416  * Callback which will be called to after a host registration succeeded or failed
417  *
418  * @param cls the host which has been registered
419  * @param emsg the error message; NULL if host registration is successful
420  */
421 static void
422 registration_cont (void *cls, const char *emsg);
423
424
425 /**
426  * Signature of the event handler function called by the
427  * respective event controller.
428  *
429  * @param cls closure
430  * @param event information about the event
431  */
432 static void
433 controller_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event)
434 {
435   switch (result)
436   {
437   case SLAVE2_REGISTERED:
438     check_operation_success (event);
439     GNUNET_TESTBED_operation_done (op);
440     op = NULL;
441     result = SLAVE1_LINK_SUCCESS;
442     GNUNET_assert (NULL != slave2);
443     GNUNET_assert (NULL != slave);
444     op = GNUNET_TESTBED_peer_create (mc, slave, cfg, peer_create_cb, NULL);
445     GNUNET_assert (NULL != op);
446     break;
447   case SLAVE1_PEER_START_SUCCESS:
448     check_operation_success (event);
449     GNUNET_TESTBED_operation_done (op);
450     result = SLAVE2_LINK_SUCCESS;
451     op = GNUNET_TESTBED_peer_create (mc, slave2, cfg, peer_create_cb, NULL);    
452     GNUNET_assert (NULL != op);
453     break;
454   case MASTER_PEER_CREATE_SUCCESS:
455     GNUNET_assert (GNUNET_TESTBED_ET_PEER_START == event->type);
456     GNUNET_assert (event->details.peer_start.host == host);
457     GNUNET_assert (event->details.peer_start.peer == master_peer);
458     GNUNET_TESTBED_operation_done (op);
459     result = MASTER_PEER_START_SUCCESS;
460     slave = GNUNET_TESTBED_host_create_with_id (1, "127.0.0.1", NULL, 0);
461     GNUNET_assert (NULL != slave);
462     rh = GNUNET_TESTBED_register_host (mc, slave, &registration_cont, NULL);
463     GNUNET_assert (NULL != rh);
464     break;
465   case SLAVE1_PEER_CREATE_SUCCESS:
466     GNUNET_assert (GNUNET_TESTBED_ET_PEER_START == event->type);
467     GNUNET_assert (event->details.peer_start.host == slave);
468     GNUNET_assert (event->details.peer_start.peer == slave1_peer);
469     GNUNET_TESTBED_operation_done (op);
470     result = SLAVE1_PEER_START_SUCCESS;
471     op = GNUNET_TESTBED_controller_link (NULL, mc, slave2, slave, cfg,
472                                          GNUNET_YES);  
473     break;
474   case SLAVE2_PEER_CREATE_SUCCESS:
475     GNUNET_assert (GNUNET_TESTBED_ET_PEER_STOP == event->type);
476     GNUNET_assert (event->details.peer_stop.peer == slave1_peer);
477     GNUNET_TESTBED_operation_done (op);
478     result = SLAVE1_PEER_STOP_SUCCESS;
479     op = GNUNET_TESTBED_peer_start (NULL, slave2_peer, NULL, NULL);
480     GNUNET_assert (NULL != op);
481     break;
482   case SLAVE1_PEER_STOP_SUCCESS:
483     GNUNET_assert (GNUNET_TESTBED_ET_PEER_START == event->type);
484     GNUNET_assert (event->details.peer_start.host == slave2);
485     GNUNET_assert (event->details.peer_start.peer == slave2_peer);
486     GNUNET_TESTBED_operation_done (op);
487     result = SLAVE2_PEER_START_SUCCESS;
488     op = GNUNET_TESTBED_overlay_connect (mc, NULL, NULL, master_peer,
489                                          slave2_peer);
490     break;
491   case SLAVE2_PEER_START_SUCCESS:
492     GNUNET_assert (NULL != event);
493     GNUNET_assert (GNUNET_TESTBED_ET_CONNECT == event->type);
494     GNUNET_assert (event->details.peer_connect.peer1 == master_peer);
495     GNUNET_assert (event->details.peer_connect.peer2 == slave2_peer);
496     result = MASTER_SLAVE2_PEERS_CONNECTED;
497     GNUNET_TESTBED_operation_done (op);
498     op = NULL;
499     GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
500                                   (GNUNET_TIME_UNIT_SECONDS, 1), &delay_task,
501                                   NULL);
502     break;
503   case MASTER_SLAVE2_PEERS_CONNECTED:
504     GNUNET_assert (GNUNET_TESTBED_ET_PEER_STOP == event->type);
505     GNUNET_assert (event->details.peer_stop.peer == slave2_peer);
506     GNUNET_TESTBED_operation_done (op);
507     result = SLAVE2_PEER_STOP_SUCCESS;
508     op = GNUNET_TESTBED_peer_destroy (slave1_peer);
509     GNUNET_assert (NULL != op);
510     break;
511   case SLAVE2_PEER_STOP_SUCCESS:
512     check_operation_success (event);
513     GNUNET_TESTBED_operation_done (op);
514     result = SLAVE1_PEER_DESTROY_SUCCESS;
515     op = GNUNET_TESTBED_peer_destroy (slave2_peer);
516     GNUNET_assert (NULL != op);
517     break;
518   case SLAVE1_PEER_DESTROY_SUCCESS:
519     check_operation_success (event);
520     GNUNET_TESTBED_operation_done (op);
521     op = NULL;
522     result = SLAVE2_PEER_DESTROY_SUCCESS;
523     slave3 = GNUNET_TESTBED_host_create_with_id (3, "127.0.0.1", NULL, 0);
524     rh = GNUNET_TESTBED_register_host (mc, slave3, &registration_cont, NULL);
525     break;
526   case SLAVE3_REGISTERED:
527     check_operation_success (event);
528     GNUNET_TESTBED_operation_done (op);
529     op = NULL;
530     result = SLAVE3_STARTED;
531     op = GNUNET_TESTBED_get_slave_config (NULL, mc, slave3);
532     GNUNET_assert (NULL != op);    
533     break;
534   case SLAVE3_STARTED:
535     GNUNET_assert (NULL != event);
536     GNUNET_assert (GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type);
537     GNUNET_assert (event->details.operation_finished.operation == op);
538     GNUNET_assert (NULL == event->details.operation_finished.op_cls);
539     GNUNET_assert (NULL == event->details.operation_finished.emsg);
540     cfg3 = GNUNET_CONFIGURATION_dup (event->details.operation_finished.generic);
541     GNUNET_TESTBED_operation_done (op);
542     result = SLAVE3_GET_CONFIG_SUCCESS;
543     op = GNUNET_TESTBED_controller_link (NULL, mc, slave3, slave, cfg3, GNUNET_NO);
544     break;
545   case SLAVE3_GET_CONFIG_SUCCESS:
546     result = SLAVE3_LINK_SUCCESS;
547     GNUNET_TESTBED_operation_done (op);
548     op = GNUNET_TESTBED_peer_destroy (master_peer);
549     break;
550  case SLAVE3_LINK_SUCCESS:
551    check_operation_success (event);
552    result = SUCCESS;
553    GNUNET_TESTBED_operation_done (op);
554    op = NULL;       
555    GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
556                                  (GNUNET_TIME_UNIT_SECONDS, 3),
557                                  &do_shutdown, NULL);
558    break;
559   default:
560     GNUNET_assert (0);
561   }
562 }
563
564
565 /**
566  * Callback which will be called to after a host registration succeeded or failed
567  *
568  * @param cls the host which has been registered
569  * @param emsg the error message; NULL if host registration is successful
570  */
571 static void
572 registration_cont (void *cls, const char *emsg)
573 {
574   rh = NULL;
575   switch (result)
576   {
577   case MASTER_PEER_START_SUCCESS:
578     GNUNET_assert (NULL == emsg);
579     GNUNET_assert (NULL != mc);
580     result = SLAVE1_REGISTERED;
581     slave2 = GNUNET_TESTBED_host_create_with_id (2, "127.0.0.1", NULL, 0);
582     GNUNET_assert (NULL != slave2);
583     rh = GNUNET_TESTBED_register_host (mc, slave2, &registration_cont, NULL);
584     GNUNET_assert (NULL != rh);
585     break;
586   case SLAVE1_REGISTERED:
587     GNUNET_assert (NULL == emsg);
588     GNUNET_assert (NULL != mc);
589     result = SLAVE2_REGISTERED;
590     GNUNET_assert (NULL != cfg);
591     op = GNUNET_TESTBED_controller_link (NULL, mc, slave, NULL, cfg, GNUNET_YES);
592     GNUNET_assert (NULL != op);
593     break;
594   case SLAVE2_PEER_DESTROY_SUCCESS:
595     GNUNET_assert (NULL == emsg);
596     GNUNET_assert (NULL != mc);
597     GNUNET_assert (NULL == op);
598     result = SLAVE3_REGISTERED;
599     op = GNUNET_TESTBED_controller_link (NULL, mc, slave3, NULL, cfg, GNUNET_YES);
600     GNUNET_assert (NULL != op);
601     break;
602   default:
603     GNUNET_break (0);
604     do_abort_now (NULL);
605   }
606 }
607
608 /**
609  * Callback to signal successfull startup of the controller process
610  *
611  * @param cls the closure from GNUNET_TESTBED_controller_start()
612  * @param cfg the configuration with which the controller has been started;
613  *          NULL if status is not GNUNET_OK
614  * @param status GNUNET_OK if the startup is successfull; GNUNET_SYSERR if not,
615  *          GNUNET_TESTBED_controller_stop() shouldn't be called in this case
616  */
617 static void
618 status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *config,
619            int status)
620 {
621   switch (result)
622   {
623   case INIT:
624     GNUNET_assert (GNUNET_OK == status);
625     event_mask = 0;
626     event_mask |= (1L << GNUNET_TESTBED_ET_PEER_START);
627     event_mask |= (1L << GNUNET_TESTBED_ET_PEER_STOP);
628     event_mask |= (1L << GNUNET_TESTBED_ET_CONNECT);
629     event_mask |= (1L << GNUNET_TESTBED_ET_OPERATION_FINISHED);
630     mc = GNUNET_TESTBED_controller_connect (config, host, event_mask,
631                                             &controller_cb, NULL);
632     GNUNET_assert (NULL != mc);
633     result = MASTER_STARTED;
634     op = GNUNET_TESTBED_peer_create (mc, host, cfg, peer_create_cb, NULL);
635     GNUNET_assert (NULL != op);
636     break;
637   default:    
638     GNUNET_break (0);
639     cp = NULL;
640     do_abort_now (NULL);
641   }
642 }
643
644
645 /**
646  * Callbacks of this type are called by GNUNET_TESTBED_is_host_habitable to
647  * inform whether the given host is habitable or not. The Handle returned by
648  * GNUNET_TESTBED_is_host_habitable() is invalid after this callback is called
649  *
650  * @param cls NULL
651  * @param host the host whose status is being reported; will be NULL if the host
652  *          given to GNUNET_TESTBED_is_host_habitable() is NULL
653  * @param status GNUNET_YES if it is habitable; GNUNET_NO if not
654  */
655 static void 
656 host_habitable_cb (void *cls, const struct GNUNET_TESTBED_Host *_host, int status)
657 {
658   hc_handle = NULL;
659   if (GNUNET_NO == status)
660   {
661     (void) PRINTF ("%s",
662                    "Unable to run the test as this system is not configured "
663                    "to use password less SSH logins to localhost.\n"
664                    "Skipping test\n");
665     GNUNET_SCHEDULER_cancel (abort_task);
666     abort_task = GNUNET_SCHEDULER_NO_TASK;
667     (void) GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
668     result = SKIP;
669     return;
670   }
671   cp = GNUNET_TESTBED_controller_start ("127.0.0.1", host, cfg, status_cb,
672                                         NULL);  
673 }
674
675
676 /**
677  * Main run function.
678  *
679  * @param cls NULL
680  * @param args arguments passed to GNUNET_PROGRAM_run
681  * @param cfgfile the path to configuration file
682  * @param cfg the configuration file handle
683  */
684 static void
685 run (void *cls, char *const *args, const char *cfgfile,
686      const struct GNUNET_CONFIGURATION_Handle *config)
687 {
688   host = GNUNET_TESTBED_host_create (NULL, NULL, 0);
689   GNUNET_assert (NULL != host);
690   if (NULL == (hc_handle = GNUNET_TESTBED_is_host_habitable (host, config,
691                                                              &host_habitable_cb,
692                                                              NULL)))
693   {
694     GNUNET_TESTBED_host_destroy (host);
695     host = NULL;
696     (void) PRINTF ("%s",
697                    "Unable to run the test as this system is not configured "
698                    "to use password less SSH logins to localhost.\n"
699                    "Marking test as successful\n");
700     result = SKIP;
701     return;
702   }
703   cfg = GNUNET_CONFIGURATION_dup (config);  
704   abort_task =
705       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
706                                     (GNUNET_TIME_UNIT_MINUTES, 5), &do_abort,
707                                     NULL);
708 }
709
710
711 /**
712  * Main function
713  */
714 int
715 main (int argc, char **argv)
716 {
717   char *const argv2[] = { "test_testbed_api_controllerlink",
718     "-c", "test_testbed_api.conf",
719     NULL
720   };
721   struct GNUNET_GETOPT_CommandLineOption options[] = {
722     GNUNET_GETOPT_OPTION_END
723   };
724   int ret;
725
726   result = INIT;
727   ret =
728       GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
729                           "test_testbed_api_controllerlink", "nohelp", options,
730                           &run, NULL);
731   if (GNUNET_OK != ret)
732     return 1;
733   switch (result)
734   {
735   case SUCCESS:
736     return 0;
737   case SKIP:
738     return 77;                  /* Mark test as skipped */
739   default:
740     return 1;
741   }
742 }
743
744 /* end of test_testbed_api_controllerlink.c */
745