7bcb8b5a7cb11a21a5aa0f24a64b0bf9274e376b
[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-new.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
175 /**
176  * Host for running master controller
177  */
178 static struct GNUNET_TESTBED_Host *host;
179
180 /**
181  * The master controller process
182  */
183 static struct GNUNET_TESTBED_ControllerProc *cp;
184
185 /**
186  * Handle to master controller
187  */
188 static struct GNUNET_TESTBED_Controller *mc;
189
190 /**
191  * Slave host for running slave controller
192  */
193 static struct GNUNET_TESTBED_Host *slave;
194
195 /**
196  * Another slave host for running another slave controller
197  */
198 static struct GNUNET_TESTBED_Host *slave2;
199
200 /**
201  * Host for slave 3
202  */
203 static struct GNUNET_TESTBED_Host *slave3;
204
205 /**
206  * Slave host registration handle
207  */
208 static struct GNUNET_TESTBED_HostRegistrationHandle *rh;
209
210 /**
211  * Handle to global configuration
212  */
213 static struct GNUNET_CONFIGURATION_Handle *cfg;
214
215 /**
216  * Configuration of slave 3 controller
217  */
218 static struct GNUNET_CONFIGURATION_Handle *cfg3;
219
220 /**
221  * Abort task
222  */
223 static GNUNET_SCHEDULER_TaskIdentifier abort_task;
224
225 /**
226  * Operation handle for linking controllers
227  */
228 static struct GNUNET_TESTBED_Operation *op;
229
230 /**
231  * Handle to peer started at slave 1
232  */
233 static struct GNUNET_TESTBED_Peer *slave1_peer;
234
235 /**
236  * Handle to peer started at slave 2
237  */
238 static struct GNUNET_TESTBED_Peer *slave2_peer;
239
240 /**
241  * Handle to a peer started at master controller
242  */
243 static struct GNUNET_TESTBED_Peer *master_peer;
244
245 /**
246  * The handle for whether a host is habitable or not
247  */
248 struct GNUNET_TESTBED_HostHabitableCheckHandle *hc_handle;
249
250 /**
251  * Event mask
252  */
253 uint64_t event_mask;
254
255 /**
256  * Global testing status
257  */
258 static enum Stage result;
259
260
261 /**
262  * Shutdown nicely
263  *
264  * @param cls NULL
265  * @param tc the task context
266  */
267 static void
268 do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
269 {
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);
274   if (NULL != slave3)
275     GNUNET_TESTBED_host_destroy (slave3);
276   if (NULL != slave2)
277     GNUNET_TESTBED_host_destroy (slave2);
278   if (NULL != slave)
279     GNUNET_TESTBED_host_destroy (slave);
280   if (NULL != host)
281     GNUNET_TESTBED_host_destroy (host);
282   if (NULL != mc)
283     GNUNET_TESTBED_controller_disconnect (mc);
284   if (NULL != cfg)
285     GNUNET_CONFIGURATION_destroy (cfg);
286   if (NULL != cfg3)
287     GNUNET_CONFIGURATION_destroy (cfg3);
288   if (NULL != cp)
289     GNUNET_TESTBED_controller_stop (cp);
290   if (NULL != rh)
291     GNUNET_TESTBED_cancel_registration (rh);
292 }
293
294
295 /**
296  * abort task to run on test timed out
297  *
298  * @param cls NULL
299  * @param tc the task context
300  */
301 static void
302 do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
303 {
304   LOG (GNUNET_ERROR_TYPE_WARNING, "Test timedout -- Aborting\n");
305   abort_task = GNUNET_SCHEDULER_NO_TASK;
306   do_shutdown (cls, tc);
307 }
308
309
310 /**
311  * Calls abort now
312  *
313  * @param 
314  * @return 
315  */
316 static void
317 do_abort_now (void *cls)
318 {
319   if (GNUNET_SCHEDULER_NO_TASK != abort_task)
320     GNUNET_SCHEDULER_cancel (abort_task);
321   abort_task = GNUNET_SCHEDULER_add_now (&do_abort, NULL);
322 }
323
324
325 /**
326  * Task for inserting delay between tests
327  *
328  * @param
329  * @return
330  */
331 static void
332 delay_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
333 {
334   switch (result)
335   {
336   case SLAVE2_PEER_CREATE_SUCCESS:
337     op = GNUNET_TESTBED_peer_stop (slave1_peer, NULL, NULL);
338     GNUNET_assert (NULL != op);
339     break;
340   case MASTER_SLAVE2_PEERS_CONNECTED:
341     op = GNUNET_TESTBED_peer_stop (slave2_peer, NULL, NULL);
342     GNUNET_assert (NULL != op);
343     break;
344   default:
345     GNUNET_assert (0);
346   }
347 }
348
349
350 /**
351  * Functions of this signature are called when a peer has been successfully
352  * created
353  *
354  * @param cls the closure from GNUNET_TESTBED_peer_create()
355  * @param peer the handle for the created peer; NULL on any error during
356  *          creation
357  * @param emsg NULL if peer is not NULL; else MAY contain the error description
358  */
359 static void
360 peer_create_cb (void *cls, struct GNUNET_TESTBED_Peer *peer, const char *emsg)
361 {
362   GNUNET_assert (NULL != peer);
363   GNUNET_assert (NULL == emsg);
364   switch (result)
365   {
366   case MASTER_STARTED:
367     result = MASTER_PEER_CREATE_SUCCESS;
368     master_peer = peer;
369     GNUNET_TESTBED_operation_done (op);
370     op = GNUNET_TESTBED_peer_start (NULL, master_peer, NULL, NULL);
371     break;
372   case SLAVE1_LINK_SUCCESS:
373     result = SLAVE1_PEER_CREATE_SUCCESS;
374     slave1_peer = peer;
375     GNUNET_TESTBED_operation_done (op);   
376     op = GNUNET_TESTBED_peer_start (NULL, slave1_peer, NULL, NULL);
377     break;
378   case SLAVE2_LINK_SUCCESS:
379     result = SLAVE2_PEER_CREATE_SUCCESS;
380     slave2_peer = peer;
381     GNUNET_TESTBED_operation_done (op);
382     GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
383                                   (GNUNET_TIME_UNIT_SECONDS, 1), &delay_task,
384                                   NULL);
385     break;
386   default:
387     GNUNET_assert (0);
388   }
389   GNUNET_assert (NULL != op);
390 }
391
392
393 /**
394  * Checks the event if it is an operation finished event and if indicates a
395  * successfull completion of operation
396  *
397  * @param event the event information to check
398  */
399 static void
400 check_operation_success (const struct GNUNET_TESTBED_EventInformation *event)
401 {
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);
408 }
409
410
411 /**
412  * Callback which will be called to after a host registration succeeded or failed
413  *
414  * @param cls the host which has been registered
415  * @param emsg the error message; NULL if host registration is successful
416  */
417 static void
418 registration_cont (void *cls, const char *emsg);
419
420
421 /**
422  * Signature of the event handler function called by the
423  * respective event controller.
424  *
425  * @param cls closure
426  * @param event information about the event
427  */
428 static void
429 controller_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event)
430 {
431   switch (result)
432   {
433   case SLAVE2_REGISTERED:
434     check_operation_success (event);
435     GNUNET_TESTBED_operation_done (op);
436     op = NULL;
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);
442     break;
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);
449     break;
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, &registration_cont, NULL);
459     GNUNET_assert (NULL != rh);
460     break;
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,
468                                          GNUNET_YES);  
469     break;
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);
477     break;
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,
485                                          slave2_peer);
486     break;
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);
494     op = NULL;
495     GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
496                                   (GNUNET_TIME_UNIT_SECONDS, 1), &delay_task,
497                                   NULL);
498     break;
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);
506     break;
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);
513     break;
514   case SLAVE1_PEER_DESTROY_SUCCESS:
515     check_operation_success (event);
516     GNUNET_TESTBED_operation_done (op);
517     op = NULL;
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, &registration_cont, NULL);
521     break;
522   case SLAVE3_REGISTERED:
523     check_operation_success (event);
524     GNUNET_TESTBED_operation_done (op);
525     op = NULL;
526     result = SLAVE3_STARTED;
527     op = GNUNET_TESTBED_get_slave_config (NULL, mc, slave3);
528     GNUNET_assert (NULL != op);    
529     break;
530   case SLAVE3_STARTED:
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);
540     break;
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);
545     break;
546  case SLAVE3_LINK_SUCCESS:
547    check_operation_success (event);
548    result = SUCCESS;
549    GNUNET_TESTBED_operation_done (op);
550    op = NULL;       
551    GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
552                                  (GNUNET_TIME_UNIT_SECONDS, 3),
553                                  &do_shutdown, NULL);
554    break;
555   default:
556     GNUNET_assert (0);
557   }
558 }
559
560
561 /**
562  * Callback which will be called to after a host registration succeeded or failed
563  *
564  * @param cls the host which has been registered
565  * @param emsg the error message; NULL if host registration is successful
566  */
567 static void
568 registration_cont (void *cls, const char *emsg)
569 {
570   rh = NULL;
571   switch (result)
572   {
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, &registration_cont, NULL);
580     GNUNET_assert (NULL != rh);
581     break;
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);
589     break;
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);
597     break;
598   default:
599     GNUNET_break (0);
600     do_abort_now (NULL);
601   }
602 }
603
604 /**
605  * Callback to signal successfull startup of the controller process
606  *
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
612  */
613 static void
614 status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *config,
615            int status)
616 {
617   switch (result)
618   {
619   case INIT:
620     GNUNET_assert (GNUNET_OK == status);
621     event_mask = 0;
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);
632     break;
633   default:    
634     GNUNET_break (0);
635     cp = NULL;
636     do_abort_now (NULL);
637   }
638 }
639
640
641 /**
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
645  *
646  * @param cls NULL
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
650  */
651 static void 
652 host_habitable_cb (void *cls, const struct GNUNET_TESTBED_Host *_host, int status)
653 {
654   hc_handle = NULL;
655   if (GNUNET_NO == status)
656   {
657     LOG (GNUNET_ERROR_TYPE_ERROR, "Cannot start testbed on localhost\n");
658     GNUNET_SCHEDULER_cancel (abort_task);
659     abort_task = GNUNET_SCHEDULER_add_now (&do_abort, NULL);
660     return;
661   }
662   cp = GNUNET_TESTBED_controller_start ("127.0.0.1", host, cfg, status_cb,
663                                         NULL);  
664 }
665
666
667 /**
668  * Main run function.
669  *
670  * @param cls NULL
671  * @param args arguments passed to GNUNET_PROGRAM_run
672  * @param cfgfile the path to configuration file
673  * @param cfg the configuration file handle
674  */
675 static void
676 run (void *cls, char *const *args, const char *cfgfile,
677      const struct GNUNET_CONFIGURATION_Handle *config)
678 {
679   host = GNUNET_TESTBED_host_create (NULL, NULL, 0);
680   GNUNET_assert (NULL != host);
681   if (NULL == (hc_handle = GNUNET_TESTBED_is_host_habitable (host, config,
682                                                              &host_habitable_cb,
683                                                              NULL)))
684   {
685     GNUNET_TESTBED_host_destroy (host);
686     host = NULL;
687     (void) PRINTF ("%s",
688                    "Unable to run the test as this system is not configured "
689                    "to use password less SSH logins to localhost.\n"
690                    "Marking test as successful\n");
691     result = SUCCESS;
692     return;
693   }
694   cfg = GNUNET_CONFIGURATION_dup (config);  
695   abort_task =
696       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
697                                     (GNUNET_TIME_UNIT_MINUTES, 5), &do_abort,
698                                     NULL);
699 }
700
701
702 /**
703  * Main function
704  */
705 int
706 main (int argc, char **argv)
707 {
708   char *const argv2[] = { "test_testbed_api_controllerlink",
709     "-c", "test_testbed_api.conf",
710     NULL
711   };
712   struct GNUNET_GETOPT_CommandLineOption options[] = {
713     GNUNET_GETOPT_OPTION_END
714   };
715   int ret;
716
717   result = INIT;
718   ret =
719       GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
720                           "test_testbed_api_controllerlink", "nohelp", options,
721                           &run, NULL);
722   if ((GNUNET_OK != ret) || (SUCCESS != result))
723     return 1;
724   return 0;
725 }
726
727 /* end of test_testbed_api_controllerlink.c */
728