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