-remove debug message
[oweals/gnunet.git] / src / testbed / test_testbed_api_3peers_3controllers.c
1 /*
2       This file is part of GNUnet
3       Copyright (C) 2008--2013 GNUnet e.V.
4
5       GNUnet is free software: you can redistribute it and/or modify it
6       under the terms of the GNU Affero General Public License as published
7       by the Free Software Foundation, either version 3 of the License,
8       or (at your 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       Affero General Public License for more details.
14
15       You should have received a copy of the GNU Affero General Public License
16       along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19  */
20
21 /**
22  * @file testbed/test_testbed_api_3peers_3controllers.c
23  * @brief testcases for the testbed api: 3 peers are configured, started and
24  *          connected together. Each peer resides on its own controller.
25  * @author Sree Harsha Totakura
26  */
27
28
29 /**
30  * The testing architecture is:
31  *                  A
32  *                 / \
33  *                /   \
34  *               B === C
35  * A is the master controller and B, C are slave controllers. B links to C
36  * laterally.
37  * Peers are mapped to controllers in the following relations:
38  *             Peer         Controller
39  *               1              A
40  *               2              B
41  *               3              C
42  *
43  */
44
45 #include "platform.h"
46 #include "gnunet_util_lib.h"
47 #include "gnunet_testing_lib.h"
48 #include "gnunet_testbed_service.h"
49
50
51 /**
52  * Generic logging shortcut
53  */
54 #define LOG(kind, ...)                           \
55   GNUNET_log (kind, __VA_ARGS__)
56
57 /**
58  * Relative time seconds shorthand
59  */
60 #define TIME_REL_SECS(sec) \
61   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, sec)
62
63
64 /**
65  * Peer context
66  */
67 struct PeerContext
68 {
69   /**
70    * The peer handle
71    */
72   struct GNUNET_TESTBED_Peer *peer;
73
74   /**
75    * Operations involving this peer
76    */
77   struct GNUNET_TESTBED_Operation *operation;
78
79   /**
80    * set to GNUNET_YES when peer is started
81    */
82   int is_running;
83 };
84
85 /**
86  * Our localhost
87  */
88 static struct GNUNET_TESTBED_Host *host;
89
90 /**
91  * The controller process of one controller
92  */
93 static struct GNUNET_TESTBED_ControllerProc *cp1;
94
95 /**
96  * A neighbouring host
97  */
98 static struct GNUNET_TESTBED_Host *neighbour1;
99
100 /**
101  * Another neighbouring host
102  */
103 static struct GNUNET_TESTBED_Host *neighbour2;
104
105 /**
106  * Handle for neighbour registration
107  */
108 static struct GNUNET_TESTBED_HostRegistrationHandle *reg_handle;
109
110 /**
111  * The controller handle of one controller
112  */
113 static struct GNUNET_TESTBED_Controller *controller1;
114
115 /**
116  * peer 1
117  */
118 static struct PeerContext peer1;
119
120 /**
121  * peer2
122  */
123 static struct PeerContext peer2;
124
125 /**
126  * peer3
127  */
128 static struct PeerContext peer3;
129
130 /**
131  * Handle to starting configuration
132  */
133 static struct GNUNET_CONFIGURATION_Handle *cfg;
134
135 /**
136  * Handle to slave controller C's configuration, used to establish lateral link from
137  * master controller
138  */
139 static struct GNUNET_CONFIGURATION_Handle *cfg2;
140
141 /**
142  * Handle to operations involving both peers
143  */
144 static struct GNUNET_TESTBED_Operation *common_operation;
145
146 /**
147  * The handle for whether a host is habitable or not
148  */
149 struct GNUNET_TESTBED_HostHabitableCheckHandle *hc_handle;
150
151 /**
152  * Abort task identifier
153  */
154 static struct GNUNET_SCHEDULER_Task *abort_task;
155
156 /**
157  * Delayed connect job identifier
158  */
159 static struct GNUNET_SCHEDULER_Task *delayed_connect_task;
160
161 /**
162  * Different stages in testing
163  */
164 enum Stage
165 {
166   /**
167    * Initial stage
168    */
169   INIT,
170
171   /**
172    * Controller 1 has started
173    */
174   CONTROLLER1_UP,
175
176   /**
177    * peer1 is created
178    */
179   PEER1_CREATED,
180
181   /**
182    * peer1 is started
183    */
184   PEER1_STARTED,
185
186   /**
187    * Controller 2 has started
188    */
189   CONTROLLER2_UP,
190
191   /**
192    * peer2 is created
193    */
194   PEER2_CREATED,
195
196   /**
197    * peer2 is started
198    */
199   PEER2_STARTED,
200
201   /**
202    * Controller 3 has started
203    */
204   CONTROLLER3_UP,
205
206   /**
207    * Peer3 is created
208    */
209   PEER3_CREATED,
210
211   /**
212    * Peer3 started
213    */
214   PEER3_STARTED,
215
216   /**
217    * peer1 and peer2 are connected
218    */
219   PEERS_1_2_CONNECTED,
220
221   /**
222    * peer2 and peer3 are connected
223    */
224   PEERS_2_3_CONNECTED,
225
226   /**
227    * Peers are connected once again (this should not fail as they are already connected)
228    */
229   PEERS_CONNECTED_2,
230
231   /**
232    * peers are stopped
233    */
234   PEERS_STOPPED,
235
236   /**
237    * Final success stage
238    */
239   SUCCESS,
240
241   /**
242    * Optional stage for marking test to be skipped
243    */
244   SKIP
245 };
246
247 /**
248  * The testing result
249  */
250 static enum Stage result;
251
252 /**
253  * Shutdown nicely
254  *
255  * @param cls NULL
256  */
257 static void
258 do_shutdown (void *cls)
259 {
260   if (NULL != abort_task)
261     GNUNET_SCHEDULER_cancel (abort_task);
262   if (NULL != hc_handle)
263     GNUNET_TESTBED_is_host_habitable_cancel (hc_handle);
264   GNUNET_assert (NULL == delayed_connect_task);
265   if (NULL != common_operation)
266     GNUNET_TESTBED_operation_done (common_operation);
267   if (NULL != reg_handle)
268     GNUNET_TESTBED_cancel_registration (reg_handle);
269   if (NULL != controller1)
270     GNUNET_TESTBED_controller_disconnect (controller1);
271   GNUNET_CONFIGURATION_destroy (cfg);
272   if (NULL != cfg2)
273     GNUNET_CONFIGURATION_destroy (cfg2);
274   if (NULL != cp1)
275     GNUNET_TESTBED_controller_stop (cp1);
276   if (NULL != host)
277     GNUNET_TESTBED_host_destroy (host);
278   if (NULL != neighbour1)
279     GNUNET_TESTBED_host_destroy (neighbour1);
280   if (NULL != neighbour2)
281     GNUNET_TESTBED_host_destroy (neighbour2);
282 }
283
284
285 /**
286  * abort task to run on test timed out
287  *
288  * @param cls NULL
289  */
290 static void
291 do_abort (void *cls)
292 {
293   LOG (GNUNET_ERROR_TYPE_WARNING, "Test timedout -- Aborting\n");
294   abort_task = NULL;
295   if (NULL != delayed_connect_task)
296   {
297     GNUNET_SCHEDULER_cancel (delayed_connect_task);
298     delayed_connect_task = NULL;
299   }
300   do_shutdown (cls);
301 }
302
303
304 static void
305 abort_test ()
306 {
307   if (NULL != abort_task)
308     GNUNET_SCHEDULER_cancel (abort_task);
309   abort_task = GNUNET_SCHEDULER_add_now (&do_abort, NULL);
310 }
311
312
313 /**
314  * Callback to be called when an operation is completed
315  *
316  * @param cls the callback closure from functions generating an operation
317  * @param op the operation that has been finished
318  * @param emsg error message in case the operation has failed; will be NULL if
319  *          operation has executed successfully.
320  */
321 static void
322 op_comp_cb (void *cls, struct GNUNET_TESTBED_Operation *op, const char *emsg);
323
324
325 /**
326  * task for delaying a connect
327  *
328  * @param cls NULL
329  */
330 static void
331 do_delayed_connect (void *cls)
332 {
333   delayed_connect_task = NULL;
334   if (NULL != common_operation)
335   {
336     GNUNET_break (0);
337     abort_test ();
338     return;
339   }
340   common_operation =
341     GNUNET_TESTBED_overlay_connect (NULL, &op_comp_cb, NULL, peer1.peer,
342                                     peer2.peer);
343 }
344
345
346 /**
347  * Callback to be called when an operation is completed
348  *
349  * @param cls the callback closure from functions generating an operation
350  * @param op the operation that has been finished
351  * @param emsg error message in case the operation has failed; will be NULL if
352  *          operation has executed successfully.
353  */
354 static void
355 op_comp_cb (void *cls, struct GNUNET_TESTBED_Operation *op, const char *emsg)
356 {
357   if (common_operation != op)
358   {
359     GNUNET_break (0);
360     abort_test ();
361     return;
362   }
363
364   switch (result)
365   {
366   case PEER3_STARTED:
367   case PEERS_2_3_CONNECTED:
368   case PEERS_1_2_CONNECTED:
369     break;
370
371   default:
372     GNUNET_break (0);
373     abort_test ();
374     return;
375   }
376   if ((NULL != peer1.operation) || (NULL != peer2.operation) ||
377       (NULL != peer3.operation))
378   {
379     GNUNET_break (0);
380     abort_test ();
381     return;
382   }
383 }
384
385
386 /**
387  * Functions of this signature are called when a peer has been successfully
388  * created
389  *
390  * @param cls NULL
391  * @param peer the handle for the created peer; NULL on any error during
392  *          creation
393  * @param emsg NULL if peer is not NULL; else MAY contain the error description
394  */
395 static void
396 peer_create_cb (void *cls, struct GNUNET_TESTBED_Peer *peer, const char *emsg)
397 {
398   switch (result)
399   {
400   case CONTROLLER1_UP:
401     if ((NULL == peer1.operation) || (NULL == peer) || (NULL != peer1.peer))
402     {
403       GNUNET_break (0);
404       abort_test ();
405       return;
406     }
407     peer1.peer = peer;
408     GNUNET_TESTBED_operation_done (peer1.operation);
409     result = PEER1_CREATED;
410     peer1.operation = GNUNET_TESTBED_peer_start (NULL, peer, NULL, NULL);
411     break;
412
413   case CONTROLLER2_UP:
414     if ((NULL == peer2.operation) || (NULL == peer) || (NULL != peer2.peer))
415     {
416       GNUNET_break (0);
417       abort_test ();
418       return;
419     }
420     peer2.peer = peer;
421     GNUNET_TESTBED_operation_done (peer2.operation);
422     result = PEER2_CREATED;
423     peer2.operation = GNUNET_TESTBED_peer_start (NULL, peer, NULL, NULL);
424     break;
425
426   case CONTROLLER3_UP:
427     if ((NULL == peer3.operation) || (NULL == peer) || (NULL != peer3.peer))
428     {
429       GNUNET_break (0);
430       abort_test ();
431       return;
432     }
433     peer3.peer = peer;
434     GNUNET_TESTBED_operation_done (peer3.operation);
435     result = PEER3_CREATED;
436     peer3.operation = GNUNET_TESTBED_peer_start (NULL, peer, NULL, NULL);
437     break;
438
439   default:
440     GNUNET_break (0);
441     abort_test ();
442     return;
443   }
444 }
445
446
447 /**
448  * Signature of the event handler function called by the
449  * respective event controller.
450  *
451  * @param cls closure
452  * @param event information about the event
453  */
454 static void
455 controller_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event)
456 {
457   switch (event->type)
458   {
459   case GNUNET_TESTBED_ET_OPERATION_FINISHED:
460     if ((NULL != event->op_cls) ||
461         (NULL != event->details.operation_finished.emsg))
462     {
463       GNUNET_break (0);
464       abort_test ();
465       return;
466     }
467     switch (result)
468     {
469     case PEERS_STOPPED:
470       if (NULL != event->details.operation_finished.generic)
471       {
472         GNUNET_break (0);
473         abort_test ();
474         return;
475       }
476       if (event->op == peer1.operation)
477       {
478         GNUNET_TESTBED_operation_done (peer1.operation);
479         peer1.operation = NULL;
480         peer1.peer = NULL;
481       }
482       else if (event->op == peer2.operation)
483       {
484         GNUNET_TESTBED_operation_done (peer2.operation);
485         peer2.operation = NULL;
486         peer2.peer = NULL;
487       }
488       else if (event->op == peer3.operation)
489       {
490         GNUNET_TESTBED_operation_done (peer3.operation);
491         peer3.operation = NULL;
492         peer3.peer = NULL;
493       }
494       else
495       {
496         GNUNET_break (0);
497         abort_test ();
498         return;
499       }
500       if ((NULL == peer1.peer) && (NULL == peer2.peer) && (NULL == peer3.peer))
501       {
502         result = SUCCESS;
503         GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
504       }
505       break;
506
507     case PEER1_STARTED:
508       if ((NULL != event->details.operation_finished.generic) ||
509           (NULL == common_operation))
510       {
511         GNUNET_break (0);
512         abort_test ();
513         return;
514       }
515       GNUNET_TESTBED_operation_done (common_operation);
516       common_operation = NULL;
517       result = CONTROLLER2_UP;
518       peer2.operation =
519         GNUNET_TESTBED_peer_create (controller1, neighbour1, cfg,
520                                     &peer_create_cb, NULL);
521       if (NULL == peer2.operation)
522       {
523         GNUNET_break (0);
524         abort_test ();
525         return;
526       }
527       break;
528
529     case PEER2_STARTED:
530       if ((NULL != event->details.operation_finished.generic) ||
531           (NULL == common_operation))
532       {
533         GNUNET_break (0);
534         abort_test ();
535         return;
536       }
537       GNUNET_TESTBED_operation_done (common_operation);
538       common_operation = NULL;
539       result = CONTROLLER3_UP;
540       peer3.operation =
541         GNUNET_TESTBED_peer_create (controller1, neighbour2, cfg,
542                                     &peer_create_cb, NULL);
543       if (NULL == peer3.operation)
544       {
545         GNUNET_break (0);
546         abort_test ();
547         return;
548       }
549       break;
550
551     default:
552       GNUNET_break (0);
553       abort_test ();
554       return;
555     }
556     break;
557
558   case GNUNET_TESTBED_ET_PEER_START:
559     switch (result)
560     {
561     case PEER1_CREATED:
562       if (event->details.peer_start.host != host)
563       {
564         GNUNET_break (0);
565         abort_test ();
566         return;
567       }
568       peer1.is_running = GNUNET_YES;
569       GNUNET_TESTBED_operation_done (peer1.operation);
570       peer1.operation = NULL;
571       result = PEER1_STARTED;
572       common_operation =
573         GNUNET_TESTBED_controller_link (NULL, controller1, neighbour1, NULL,
574                                         GNUNET_YES);
575       break;
576
577     case PEER2_CREATED:
578       if (event->details.peer_start.host != neighbour1)
579       {
580         GNUNET_break (0);
581         abort_test ();
582         return;
583       }
584       peer2.is_running = GNUNET_YES;
585       GNUNET_TESTBED_operation_done (peer2.operation);
586       peer2.operation = NULL;
587       result = PEER2_STARTED;
588       if (NULL != common_operation)
589       {
590         GNUNET_break (0);
591         abort_test ();
592         return;
593       }
594       common_operation =
595         GNUNET_TESTBED_controller_link (NULL, controller1, neighbour2, NULL,
596                                         GNUNET_YES);
597       if (NULL == common_operation)
598       {
599         GNUNET_break (0);
600         abort_test ();
601         return;
602       }
603       break;
604
605     case PEER3_CREATED:
606       if (event->details.peer_start.host != neighbour2)
607       {
608         GNUNET_break (0);
609         abort_test ();
610         return;
611       }
612       peer3.is_running = GNUNET_YES;
613       GNUNET_TESTBED_operation_done (peer3.operation);
614       peer3.operation = NULL;
615       result = PEER3_STARTED;
616       common_operation =
617         GNUNET_TESTBED_overlay_connect (NULL, &op_comp_cb, NULL, peer2.peer,
618                                         peer1.peer);
619       break;
620
621     default:
622       GNUNET_break (0);
623       abort_test ();
624       return;
625     }
626     break;
627
628   case GNUNET_TESTBED_ET_PEER_STOP:
629     if (PEERS_CONNECTED_2 != result)
630     {
631       GNUNET_break (0);
632       abort_test ();
633       return;
634     }
635     if (event->details.peer_stop.peer == peer1.peer)
636     {
637       peer1.is_running = GNUNET_NO;
638       GNUNET_TESTBED_operation_done (peer1.operation);
639     }
640     else if (event->details.peer_stop.peer == peer2.peer)
641     {
642       peer2.is_running = GNUNET_NO;
643       GNUNET_TESTBED_operation_done (peer2.operation);
644     }
645     else if (event->details.peer_stop.peer == peer3.peer)
646     {
647       peer3.is_running = GNUNET_NO;
648       GNUNET_TESTBED_operation_done (peer3.operation);
649     }
650     else
651     {
652       GNUNET_break (0);
653       abort_test ();
654       return;
655     }
656     if ((GNUNET_NO == peer1.is_running) && (GNUNET_NO == peer2.is_running) &&
657         (GNUNET_NO == peer3.is_running))
658     {
659       result = PEERS_STOPPED;
660       peer1.operation = GNUNET_TESTBED_peer_destroy (peer1.peer);
661       peer2.operation = GNUNET_TESTBED_peer_destroy (peer2.peer);
662       peer3.operation = GNUNET_TESTBED_peer_destroy (peer3.peer);
663     }
664     break;
665
666   case GNUNET_TESTBED_ET_CONNECT:
667     if ((NULL != peer1.operation) || (NULL != peer2.operation) ||
668         (NULL != peer3.operation) || (NULL == common_operation))
669     {
670       GNUNET_break (0);
671       abort_test ();
672       return;
673     }
674     switch (result)
675     {
676     case PEER3_STARTED:
677       if ((event->details.peer_connect.peer1 != peer2.peer) ||
678           (event->details.peer_connect.peer2 != peer1.peer))
679       {
680         GNUNET_break (0);
681         abort_test ();
682         return;
683       }
684       GNUNET_TESTBED_operation_done (common_operation);
685       common_operation = NULL;
686       result = PEERS_1_2_CONNECTED;
687       LOG (GNUNET_ERROR_TYPE_DEBUG, "Peers connected\n");
688       common_operation =
689         GNUNET_TESTBED_overlay_connect (NULL, &op_comp_cb, NULL, peer2.peer,
690                                         peer3.peer);
691       break;
692
693     case PEERS_1_2_CONNECTED:
694       if ((event->details.peer_connect.peer1 != peer2.peer) ||
695           (event->details.peer_connect.peer2 != peer3.peer))
696       {
697         GNUNET_break (0);
698         abort_test ();
699         return;
700       }
701       GNUNET_TESTBED_operation_done (common_operation);
702       common_operation = NULL;
703       result = PEERS_2_3_CONNECTED;
704       delayed_connect_task =
705         GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS (3), &do_delayed_connect,
706                                       NULL);
707       break;
708
709     case PEERS_2_3_CONNECTED:
710       if ((event->details.peer_connect.peer1 != peer1.peer) ||
711           (event->details.peer_connect.peer2 != peer2.peer))
712       {
713         GNUNET_break (0);
714         abort_test ();
715         return;
716       }
717       GNUNET_TESTBED_operation_done (common_operation);
718       common_operation = NULL;
719       result = PEERS_CONNECTED_2;
720       LOG (GNUNET_ERROR_TYPE_DEBUG, "Peers connected again\n");
721       peer1.operation = GNUNET_TESTBED_peer_stop (NULL, peer1.peer, NULL, NULL);
722       peer2.operation = GNUNET_TESTBED_peer_stop (NULL, peer2.peer, NULL, NULL);
723       peer3.operation = GNUNET_TESTBED_peer_stop (NULL, peer3.peer, NULL, NULL);
724       break;
725
726     default:
727       GNUNET_break (0);
728       abort_test ();
729       return;
730     }
731     break;
732
733   default:
734     GNUNET_break (0);
735     abort_test ();
736     return;
737   }
738 }
739
740
741 /**
742  * Callback which will be called to after a host registration succeeded or failed
743  *
744  * @param cls the host which has been registered
745  * @param emsg the error message; NULL if host registration is successful
746  */
747 static void
748 registration_comp (void *cls, const char *emsg)
749 {
750   reg_handle = NULL;
751   if (cls == neighbour1)
752   {
753     neighbour2 = GNUNET_TESTBED_host_create ("127.0.0.1", NULL, cfg, 0);
754     if (NULL == neighbour2)
755     {
756       GNUNET_break (0);
757       abort_test ();
758       return;
759     }
760     reg_handle =
761       GNUNET_TESTBED_register_host (controller1, neighbour2,
762                                     &registration_comp, neighbour2);
763     if (NULL == reg_handle)
764     {
765       GNUNET_break (0);
766       abort_test ();
767       return;
768     }
769     return;
770   }
771   if (cls != neighbour2)
772   {
773     GNUNET_break (0);
774     abort_test ();
775     return;
776   }
777   peer1.operation =
778     GNUNET_TESTBED_peer_create (controller1, host, cfg, &peer_create_cb,
779                                 &peer1);
780   if (NULL == peer1.operation)
781   {
782     GNUNET_break (0);
783     abort_test ();
784     return;
785   }
786 }
787
788
789 /**
790  * Callback to signal successfull startup of the controller process
791  *
792  * @param cls the closure from GNUNET_TESTBED_controller_start()
793  * @param cfg the configuration with which the controller has been started;
794  *          NULL if status is not GNUNET_OK
795  * @param status GNUNET_OK if the startup is successfull; GNUNET_SYSERR if not,
796  *          GNUNET_TESTBED_controller_stop() shouldn't be called in this case
797  */
798 static void
799 status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *config,
800            int status)
801 {
802   uint64_t event_mask;
803
804   if (GNUNET_OK != status)
805   {
806     GNUNET_break (0);
807     cp1 = NULL;
808     abort_test ();
809     return;
810   }
811   event_mask = 0;
812   event_mask |= (1L << GNUNET_TESTBED_ET_PEER_START);
813   event_mask |= (1L << GNUNET_TESTBED_ET_PEER_STOP);
814   event_mask |= (1L << GNUNET_TESTBED_ET_CONNECT);
815   event_mask |= (1L << GNUNET_TESTBED_ET_OPERATION_FINISHED);
816   switch (result)
817   {
818   case INIT:
819     controller1 =
820       GNUNET_TESTBED_controller_connect (host, event_mask,
821                                          &controller_cb, NULL);
822     if (NULL == controller1)
823     {
824       GNUNET_break (0);
825       abort_test ();
826       return;
827     }
828     result = CONTROLLER1_UP;
829     neighbour1 = GNUNET_TESTBED_host_create ("127.0.0.1", NULL, cfg, 0);
830     if (NULL == neighbour1)
831     {
832       GNUNET_break (0);
833       abort_test ();
834       return;
835     }
836     reg_handle =
837       GNUNET_TESTBED_register_host (controller1, neighbour1,
838                                     &registration_comp, neighbour1);
839     if (NULL == reg_handle)
840     {
841       GNUNET_break (0);
842       abort_test ();
843       return;
844     }
845     break;
846
847   default:
848     GNUNET_break (0);
849     abort_test ();
850     return;
851   }
852 }
853
854
855 /**
856  * Callbacks of this type are called by GNUNET_TESTBED_is_host_habitable to
857  * inform whether the given host is habitable or not. The Handle returned by
858  * GNUNET_TESTBED_is_host_habitable() is invalid after this callback is called
859  *
860  * @param cls NULL
861  * @param host the host whose status is being reported; will be NULL if the host
862  *          given to GNUNET_TESTBED_is_host_habitable() is NULL
863  * @param status #GNUNET_YES if it is habitable; #GNUNET_NO if not
864  */
865 static void
866 host_habitable_cb (void *cls,
867                    const struct GNUNET_TESTBED_Host *_host,
868                    int status)
869 {
870   hc_handle = NULL;
871   if (GNUNET_NO == status)
872   {
873     (void) printf ("%s",
874                    "Unable to run the test as this system is not configured "
875                    "to use password less SSH logins to localhost.\n"
876                    "Skipping test\n");
877     GNUNET_SCHEDULER_cancel (abort_task);
878     abort_task = NULL;
879     GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
880     result = SKIP;
881     return;
882   }
883   cp1 =
884     GNUNET_TESTBED_controller_start ("127.0.0.1", host, status_cb, NULL);
885 }
886
887
888 /**
889  * Main run function.
890  *
891  * @param cls NULL
892  * @param args arguments passed to GNUNET_PROGRAM_run
893  * @param cfgfile the path to configuration file
894  * @param cfg the configuration file handle
895  */
896 static void
897 run (void *cls, char *const *args, const char *cfgfile,
898      const struct GNUNET_CONFIGURATION_Handle *config)
899 {
900   cfg = GNUNET_CONFIGURATION_dup (config);
901   host = GNUNET_TESTBED_host_create (NULL, NULL, cfg, 0);
902   if (NULL == host)
903   {
904     GNUNET_break (0);
905     abort_test ();
906     return;
907   }
908   if (NULL ==
909       (hc_handle =
910          GNUNET_TESTBED_is_host_habitable (host, config, &host_habitable_cb,
911                                            NULL)))
912   {
913     GNUNET_TESTBED_host_destroy (host);
914     host = NULL;
915     (void) printf ("%s",
916                    "Unable to run the test as this system is not configured "
917                    "to use password less SSH logins to localhost.\n"
918                    "Skipping test\n");
919     result = SKIP;
920     return;
921   }
922   abort_task =
923     GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
924                                     (GNUNET_TIME_UNIT_MINUTES, 3), &do_abort,
925                                   NULL);
926 }
927
928
929 /**
930  * Main function
931  */
932 int
933 main (int argc, char **argv)
934 {
935   char *const argv2[] = { "test_testbed_api_3peers_3controllers",
936                           "-c", "test_testbed_api.conf",
937                           NULL };
938   struct GNUNET_GETOPT_CommandLineOption options[] = {
939     GNUNET_GETOPT_OPTION_END
940   };
941   int ret;
942
943   result = INIT;
944   ret =
945     GNUNET_PROGRAM_run ((sizeof(argv2) / sizeof(char *)) - 1, argv2,
946                         "test_testbed_api_3peers_3controllers", "nohelp",
947                         options, &run, NULL);
948   if (GNUNET_OK != ret)
949     return 1;
950   switch (result)
951   {
952   case SUCCESS:
953     return 0;
954
955   case SKIP:
956     return 77;                  /* Mark test as skipped */
957
958   default:
959     return 1;
960   }
961 }
962
963
964 /* end of test_testbed_api_3peers_3controllers.c */