-more datacache integration work
[oweals/gnunet.git] / src / testbed / test_testbed_api_controllerlink.c
1 /*
2       This file is part of GNUnet
3       Copyright (C) 2008--2013 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    * Slave 3 has successfully registered
135    */
136   SLAVE3_REGISTERED,
137
138   /**
139    * Slave 3 has successfully started
140    */
141   SLAVE3_STARTED,
142
143   /**
144    * Peer created on slave 3
145    */
146   SLAVE3_PEER_CREATE_SUCCESS,
147
148   /**
149    * Peer started at slave 3
150    */
151   SLAVE3_PEER_START_SUCCESS,
152
153   /**
154    * Try to connect peers on slave2 and slave3
155    */
156   SLAVE2_SLAVE3_PEERS_CONNECTED,
157
158   /**
159    * Peer on slave 2 successfully stopped
160    */
161   SLAVE2_PEER_STOP_SUCCESS,
162
163   /**
164    * Peer destroy on slave 1 successful
165    */
166   SLAVE1_PEER_DESTROY_SUCCESS,
167
168   /**
169    * Peer destory on slave 2 successful
170    */
171   SLAVE2_PEER_DESTROY_SUCCESS,
172
173   /**
174    * The configuration of slave 3 is acquired
175    */
176   SLAVE3_GET_CONFIG_SUCCESS,
177
178   /**
179    * Slave 1 has linked to slave 3;
180    */
181   SLAVE3_LINK_SUCCESS,
182
183   /**
184    * Master peer destoryed.  Destory slave 3 peer
185    */
186   MASTER_PEER_DESTROY_SUCCESS,
187
188   /**
189    * Slave 3 peer destroyed.  Mark test as success
190    */
191   SUCCESS,
192
193   /**
194    * Marks test as skipped
195    */
196   SKIP
197 };
198
199 /**
200  * Host for running master controller
201  */
202 static struct GNUNET_TESTBED_Host *host;
203
204 /**
205  * The master controller process
206  */
207 static struct GNUNET_TESTBED_ControllerProc *cp;
208
209 /**
210  * Handle to master controller
211  */
212 static struct GNUNET_TESTBED_Controller *mc;
213
214 /**
215  * Slave host for running slave controller
216  */
217 static struct GNUNET_TESTBED_Host *slave;
218
219 /**
220  * Another slave host for running another slave controller
221  */
222 static struct GNUNET_TESTBED_Host *slave2;
223
224 /**
225  * Host for slave 3
226  */
227 static struct GNUNET_TESTBED_Host *slave3;
228
229 /**
230  * Slave host registration handle
231  */
232 static struct GNUNET_TESTBED_HostRegistrationHandle *rh;
233
234 /**
235  * Handle to global configuration
236  */
237 static struct GNUNET_CONFIGURATION_Handle *cfg;
238
239 /**
240  * Configuration of slave 3 controller
241  */
242 static struct GNUNET_CONFIGURATION_Handle *cfg3;
243
244 /**
245  * Abort task
246  */
247 static struct GNUNET_SCHEDULER_Task * abort_task;
248
249 /**
250  * Operation handle for linking controllers
251  */
252 static struct GNUNET_TESTBED_Operation *op;
253
254 /**
255  * Handle to peer started at slave 1
256  */
257 static struct GNUNET_TESTBED_Peer *slave1_peer;
258
259 /**
260  * Handle to peer started at slave 2
261  */
262 static struct GNUNET_TESTBED_Peer *slave2_peer;
263
264 /**
265  * Handle to peer started at slave 2
266  */
267 static struct GNUNET_TESTBED_Peer *slave3_peer;
268
269 /**
270  * Handle to a peer started at master controller
271  */
272 static struct GNUNET_TESTBED_Peer *master_peer;
273
274 /**
275  * The handle for whether a host is habitable or not
276  */
277 struct GNUNET_TESTBED_HostHabitableCheckHandle *hc_handle;
278
279 /**
280  * The task handle for the delay task
281  */
282 struct GNUNET_SCHEDULER_Task * delay_task_id;
283
284 /**
285  * Event mask
286  */
287 uint64_t event_mask;
288
289 /**
290  * Global testing status
291  */
292 static enum Stage result;
293
294 /**
295  * shortcut to exit during failure
296  */
297 #define FAIL_TEST(cond) do {                                    \
298     if (!(cond)) {                                              \
299       GNUNET_break(0);                                          \
300       if (NULL != abort_task)               \
301         GNUNET_SCHEDULER_cancel (abort_task);                   \
302       abort_task = NULL;                    \
303       GNUNET_SCHEDULER_add_now (do_shutdown, NULL);             \
304       return;                                                   \
305     }                                                          \
306   } while (0)
307
308
309 /**
310  * Shutdown nicely
311  *
312  * @param cls NULL
313  * @param tc the task context
314  */
315 static void
316 do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
317 {
318   if (NULL != abort_task)
319     GNUNET_SCHEDULER_cancel (abort_task);
320   if (NULL != delay_task_id)
321   {
322     GNUNET_SCHEDULER_cancel (delay_task_id);
323     delay_task_id = NULL;
324   }
325   if (NULL != hc_handle)
326     GNUNET_TESTBED_is_host_habitable_cancel (hc_handle);
327   if (NULL != mc)
328     GNUNET_TESTBED_controller_disconnect (mc);
329   if (NULL != cp)
330     GNUNET_TESTBED_controller_stop (cp);
331   if (NULL != slave3)
332     GNUNET_TESTBED_host_destroy (slave3);
333   if (NULL != slave2)
334     GNUNET_TESTBED_host_destroy (slave2);
335   if (NULL != slave)
336     GNUNET_TESTBED_host_destroy (slave);
337   if (NULL != host)
338     GNUNET_TESTBED_host_destroy (host);
339   if (NULL != cfg)
340     GNUNET_CONFIGURATION_destroy (cfg);
341   if (NULL != cfg3)
342     GNUNET_CONFIGURATION_destroy (cfg3);
343   if (NULL != rh)
344     GNUNET_TESTBED_cancel_registration (rh);
345 }
346
347
348 /**
349  * abort task to run on test timed out
350  *
351  * @param cls NULL
352  * @param tc the task context
353  */
354 static void
355 do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
356 {
357   LOG (GNUNET_ERROR_TYPE_WARNING, "Aborting\n");
358   abort_task = NULL;
359   do_shutdown (cls, tc);
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, const struct GNUNET_SCHEDULER_TaskContext *tc)
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, struct GNUNET_TESTBED_Peer *peer, const char *emsg)
429 {
430   FAIL_TEST (NULL != peer);
431   FAIL_TEST (NULL == emsg);
432   switch (result)
433   {
434   case MASTER_STARTED:
435     result = MASTER_PEER_CREATE_SUCCESS;
436     master_peer = peer;
437     GNUNET_TESTBED_operation_done (op);
438     op = GNUNET_TESTBED_peer_start (NULL, master_peer, NULL, NULL);
439     break;
440   case SLAVE1_LINK_SUCCESS:
441     result = SLAVE1_PEER_CREATE_SUCCESS;
442     slave1_peer = peer;
443     GNUNET_TESTBED_operation_done (op);
444     op = GNUNET_TESTBED_peer_start (NULL, slave1_peer, NULL, NULL);
445     break;
446   case SLAVE2_LINK_SUCCESS:
447     result = SLAVE2_PEER_CREATE_SUCCESS;
448     slave2_peer = peer;
449     GNUNET_TESTBED_operation_done (op);
450     delay_task_id =
451         GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
452                                       (GNUNET_TIME_UNIT_SECONDS, 1),
453                                       &delay_task,
454                                       NULL);
455     break;
456   case SLAVE3_STARTED:
457     result = SLAVE3_PEER_CREATE_SUCCESS;
458     slave3_peer = peer;
459     GNUNET_TESTBED_operation_done (op);
460     op = GNUNET_TESTBED_peer_start (NULL, slave3_peer, NULL, NULL);
461     break;
462   default:
463     FAIL_TEST (0);
464   }
465   FAIL_TEST (NULL != op);
466 }
467
468
469 /**
470  * Checks the event if it is an operation finished event and if indicates a
471  * successfull completion of operation
472  *
473  * @param event the event information to check
474  */
475 static void
476 check_operation_success (const struct GNUNET_TESTBED_EventInformation *event)
477 {
478   FAIL_TEST (NULL != event);
479   FAIL_TEST (GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type);
480   FAIL_TEST (event->op == op);
481   FAIL_TEST (NULL == event->op_cls);
482   FAIL_TEST (NULL == event->details.operation_finished.emsg);
483   FAIL_TEST (NULL == event->details.operation_finished.generic);
484 }
485
486
487 /**
488  * Signature of the event handler function called by the
489  * respective event controller.
490  *
491  * @param cls closure
492  * @param event information about the event
493  */
494 static void
495 controller_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event)
496 {
497   switch (result)
498   {
499   case SLAVE2_REGISTERED:
500     check_operation_success (event);
501     GNUNET_TESTBED_operation_done (op);
502     op = NULL;
503     result = SLAVE1_LINK_SUCCESS;
504     FAIL_TEST (NULL != slave2);
505     FAIL_TEST (NULL != slave);
506     op = GNUNET_TESTBED_peer_create (mc, slave, cfg, peer_create_cb, NULL);
507     FAIL_TEST (NULL != op);
508     break;
509   case SLAVE1_PEER_START_SUCCESS:
510     check_operation_success (event);
511     GNUNET_TESTBED_operation_done (op);
512     result = SLAVE2_LINK_SUCCESS;
513     op = GNUNET_TESTBED_peer_create (mc, slave2, cfg, peer_create_cb, NULL);
514     FAIL_TEST (NULL != op);
515     break;
516   case MASTER_PEER_CREATE_SUCCESS:
517     FAIL_TEST (GNUNET_TESTBED_ET_PEER_START == event->type);
518     FAIL_TEST (event->details.peer_start.host == host);
519     FAIL_TEST (event->details.peer_start.peer == master_peer);
520     GNUNET_TESTBED_operation_done (op);
521     result = MASTER_PEER_START_SUCCESS;
522     slave = GNUNET_TESTBED_host_create_with_id (1, "127.0.0.1", NULL, cfg, 0);
523     FAIL_TEST (NULL != slave);
524     rh = GNUNET_TESTBED_register_host (mc, slave, &registration_cont, NULL);
525     FAIL_TEST (NULL != rh);
526     break;
527   case SLAVE1_PEER_CREATE_SUCCESS:
528     FAIL_TEST (GNUNET_TESTBED_ET_PEER_START == event->type);
529     FAIL_TEST (event->details.peer_start.host == slave);
530     FAIL_TEST (event->details.peer_start.peer == slave1_peer);
531     GNUNET_TESTBED_operation_done (op);
532     result = SLAVE1_PEER_START_SUCCESS;
533     op = GNUNET_TESTBED_controller_link (NULL, mc, slave2, slave, GNUNET_YES);
534     break;
535   case SLAVE2_PEER_CREATE_SUCCESS:
536     FAIL_TEST (GNUNET_TESTBED_ET_PEER_STOP == event->type);
537     FAIL_TEST (event->details.peer_stop.peer == slave1_peer);
538     GNUNET_TESTBED_operation_done (op);
539     result = SLAVE1_PEER_STOP_SUCCESS;
540     op = GNUNET_TESTBED_peer_start (NULL, slave2_peer, NULL, NULL);
541     FAIL_TEST (NULL != op);
542     break;
543   case SLAVE3_PEER_CREATE_SUCCESS:
544     FAIL_TEST (GNUNET_TESTBED_ET_PEER_START == event->type);
545     FAIL_TEST (event->details.peer_start.host == slave3);
546     FAIL_TEST (event->details.peer_start.peer == slave3_peer);
547     GNUNET_TESTBED_operation_done (op);
548     result = SLAVE3_PEER_START_SUCCESS;
549     sleep (1);
550     LOG_DEBUG ("**************************************\n");
551     op = GNUNET_TESTBED_overlay_connect (mc, NULL, NULL, slave2_peer,
552                                          slave3_peer);
553     FAIL_TEST (NULL != op);
554     break;
555   case SLAVE3_PEER_START_SUCCESS:
556     FAIL_TEST (NULL != event);
557     FAIL_TEST (GNUNET_TESTBED_ET_CONNECT == event->type);
558     FAIL_TEST (event->details.peer_connect.peer1 == slave2_peer);
559     FAIL_TEST (event->details.peer_connect.peer2 == slave3_peer);
560     result = SLAVE2_SLAVE3_PEERS_CONNECTED;
561     GNUNET_TESTBED_operation_done (op);
562     op = NULL;
563     delay_task_id =
564         GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
565                                       (GNUNET_TIME_UNIT_SECONDS, 1), &delay_task,
566                                       NULL);
567     break;
568   case SLAVE1_PEER_STOP_SUCCESS:
569     FAIL_TEST (GNUNET_TESTBED_ET_PEER_START == event->type);
570     FAIL_TEST (event->details.peer_start.host == slave2);
571     FAIL_TEST (event->details.peer_start.peer == slave2_peer);
572     GNUNET_TESTBED_operation_done (op);
573     result = SLAVE2_PEER_START_SUCCESS;
574     op = GNUNET_TESTBED_overlay_connect (mc, NULL, NULL, master_peer,
575                                          slave2_peer);
576     break;
577   case SLAVE2_PEER_START_SUCCESS:
578     FAIL_TEST (NULL != event);
579     FAIL_TEST (GNUNET_TESTBED_ET_CONNECT == event->type);
580     FAIL_TEST (event->details.peer_connect.peer1 == master_peer);
581     FAIL_TEST (event->details.peer_connect.peer2 == slave2_peer);
582     result = MASTER_SLAVE2_PEERS_CONNECTED;
583     GNUNET_TESTBED_operation_done (op);
584     op = NULL;
585     delay_task_id =
586         GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
587                                       (GNUNET_TIME_UNIT_SECONDS, 1), &delay_task,
588                                       NULL);
589     break;
590   case SLAVE2_SLAVE3_PEERS_CONNECTED:
591     FAIL_TEST (GNUNET_TESTBED_ET_PEER_STOP == event->type);
592     FAIL_TEST (event->details.peer_stop.peer == slave2_peer);
593     GNUNET_TESTBED_operation_done (op);
594     result = SLAVE2_PEER_STOP_SUCCESS;
595     op = GNUNET_TESTBED_peer_destroy (slave1_peer);
596     FAIL_TEST (NULL != op);
597     break;
598   case SLAVE2_PEER_STOP_SUCCESS:
599     check_operation_success (event);
600     GNUNET_TESTBED_operation_done (op);
601     result = SLAVE1_PEER_DESTROY_SUCCESS;
602     op = GNUNET_TESTBED_peer_destroy (slave2_peer);
603     FAIL_TEST (NULL != op);
604     break;
605   case SLAVE1_PEER_DESTROY_SUCCESS:
606     check_operation_success (event);
607     GNUNET_TESTBED_operation_done (op);
608     op = NULL;
609     result = SLAVE2_PEER_DESTROY_SUCCESS;
610     op = GNUNET_TESTBED_get_slave_config (NULL, mc, slave3);
611     FAIL_TEST (NULL != op);
612     break;
613   case SLAVE2_PEER_DESTROY_SUCCESS:
614     FAIL_TEST (NULL != event);
615     FAIL_TEST (GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type);
616     FAIL_TEST (event->op == op);
617     FAIL_TEST (NULL == event->op_cls);
618     FAIL_TEST (NULL == event->details.operation_finished.emsg);
619     cfg3 = GNUNET_CONFIGURATION_dup (event->details.operation_finished.generic);
620     GNUNET_TESTBED_operation_done (op);
621     result = SLAVE3_GET_CONFIG_SUCCESS;
622     op = GNUNET_TESTBED_controller_link (NULL, mc, slave3, slave, GNUNET_NO);
623     break;
624   case SLAVE3_REGISTERED:
625     check_operation_success (event);
626     GNUNET_TESTBED_operation_done (op);
627     op = NULL;
628     result = SLAVE3_STARTED;
629     op = GNUNET_TESTBED_peer_create (mc, slave3, cfg, peer_create_cb, NULL);
630     FAIL_TEST (NULL != op);
631     break;
632   case SLAVE3_GET_CONFIG_SUCCESS:
633     result = SLAVE3_LINK_SUCCESS;
634     GNUNET_TESTBED_operation_done (op);
635     op = GNUNET_TESTBED_peer_destroy (master_peer);
636     break;
637   case SLAVE3_LINK_SUCCESS:
638     check_operation_success (event);
639     result = MASTER_PEER_DESTROY_SUCCESS;
640     GNUNET_TESTBED_operation_done (op);
641     op = GNUNET_TESTBED_peer_destroy (slave3_peer);
642     break;
643   case MASTER_PEER_DESTROY_SUCCESS:
644     result = SUCCESS;
645     GNUNET_TESTBED_operation_done (op);
646     op = NULL;
647     GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
648                                   (GNUNET_TIME_UNIT_SECONDS, 1), &do_shutdown,
649                                   NULL);
650     break;
651   default:
652     FAIL_TEST (0);
653   }
654 }
655
656
657 /**
658  * Callback which will be called to after a host registration succeeded or failed
659  *
660  * @param cls the host which has been registered
661  * @param emsg the error message; NULL if host registration is successful
662  */
663 static void
664 registration_cont (void *cls, const char *emsg)
665 {
666   rh = NULL;
667   switch (result)
668   {
669   case MASTER_PEER_START_SUCCESS:
670     FAIL_TEST (NULL == emsg);
671     FAIL_TEST (NULL != mc);
672     result = SLAVE1_REGISTERED;
673     slave2 = GNUNET_TESTBED_host_create_with_id (2, "127.0.0.1", NULL, cfg, 0);
674     FAIL_TEST (NULL != slave2);
675     rh = GNUNET_TESTBED_register_host (mc, slave2, &registration_cont, NULL);
676     FAIL_TEST (NULL != rh);
677     break;
678   case SLAVE1_REGISTERED:
679     FAIL_TEST (NULL == emsg);
680     FAIL_TEST (NULL != mc);
681     result = SLAVE2_REGISTERED;
682     FAIL_TEST (NULL != cfg);
683     op = GNUNET_TESTBED_controller_link (NULL, mc, slave, NULL, GNUNET_YES);
684     FAIL_TEST (NULL != op);
685     break;
686   case MASTER_SLAVE2_PEERS_CONNECTED:
687     FAIL_TEST (NULL == emsg);
688     FAIL_TEST (NULL != mc);
689     FAIL_TEST (NULL == op);
690     result = SLAVE3_REGISTERED;
691     op = GNUNET_TESTBED_controller_link (NULL, mc, slave3, NULL, GNUNET_YES);
692     FAIL_TEST (NULL != op);
693     break;
694   default:
695     GNUNET_break (0);
696     do_abort_now (NULL);
697   }
698 }
699
700 /**
701  * Callback to signal successfull startup of the controller process
702  *
703  * @param cls the closure from GNUNET_TESTBED_controller_start()
704  * @param cfg the configuration with which the controller has been started;
705  *          NULL if status is not GNUNET_OK
706  * @param status GNUNET_OK if the startup is successfull; GNUNET_SYSERR if not,
707  *          GNUNET_TESTBED_controller_stop() shouldn't be called in this case
708  */
709 static void
710 status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *config,
711            int status)
712 {
713   switch (result)
714   {
715   case INIT:
716     FAIL_TEST (GNUNET_OK == status);
717     event_mask = 0;
718     event_mask |= (1L << GNUNET_TESTBED_ET_PEER_START);
719     event_mask |= (1L << GNUNET_TESTBED_ET_PEER_STOP);
720     event_mask |= (1L << GNUNET_TESTBED_ET_CONNECT);
721     event_mask |= (1L << GNUNET_TESTBED_ET_OPERATION_FINISHED);
722     mc = GNUNET_TESTBED_controller_connect (host, event_mask,
723                                             &controller_cb, NULL);
724     FAIL_TEST (NULL != mc);
725     result = MASTER_STARTED;
726     op = GNUNET_TESTBED_peer_create (mc, host, cfg, peer_create_cb, NULL);
727     FAIL_TEST (NULL != op);
728     break;
729   default:
730     GNUNET_break (0);
731     cp = NULL;
732     do_abort_now (NULL);
733   }
734 }
735
736
737 /**
738  * Callbacks of this type are called by GNUNET_TESTBED_is_host_habitable to
739  * inform whether the given host is habitable or not. The Handle returned by
740  * GNUNET_TESTBED_is_host_habitable() is invalid after this callback is called
741  *
742  * @param cls NULL
743  * @param host the host whose status is being reported; will be NULL if the host
744  *          given to GNUNET_TESTBED_is_host_habitable() is NULL
745  * @param status GNUNET_YES if it is habitable; GNUNET_NO if not
746  */
747 static void
748 host_habitable_cb (void *cls, const struct GNUNET_TESTBED_Host *_host,
749                    int status)
750 {
751   hc_handle = NULL;
752   if (GNUNET_NO == status)
753   {
754     (void) PRINTF ("%s",
755                    "Unable to run the test as this system is not configured "
756                    "to use password less SSH logins to localhost.\n"
757                    "Skipping test\n");
758     GNUNET_SCHEDULER_cancel (abort_task);
759     abort_task = NULL;
760     (void) GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
761     result = SKIP;
762     return;
763   }
764   cp = GNUNET_TESTBED_controller_start ("127.0.0.1", host, status_cb,
765                                         NULL);
766 }
767
768
769 /**
770  * Main run function.
771  *
772  * @param cls NULL
773  * @param args arguments passed to GNUNET_PROGRAM_run
774  * @param cfgfile the path to configuration file
775  * @param cfg the configuration file handle
776  */
777 static void
778 run (void *cls, char *const *args, const char *cfgfile,
779      const struct GNUNET_CONFIGURATION_Handle *config)
780 {
781   cfg = GNUNET_CONFIGURATION_dup (config);
782   host = GNUNET_TESTBED_host_create (NULL, NULL, cfg, 0);
783   FAIL_TEST (NULL != host);
784   if (NULL ==
785       (hc_handle =
786        GNUNET_TESTBED_is_host_habitable (host, config, &host_habitable_cb,
787                                          NULL)))
788   {
789     GNUNET_TESTBED_host_destroy (host);
790     GNUNET_CONFIGURATION_destroy (cfg);
791     cfg = NULL;
792     host = NULL;
793     (void) PRINTF ("%s",
794                    "Unable to run the test as this system is not configured "
795                    "to use password less SSH logins to localhost.\n"
796                    "Marking test as successful\n");
797     result = SKIP;
798     return;
799   }
800   abort_task =
801       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
802                                     (GNUNET_TIME_UNIT_MINUTES, 5), &do_abort,
803                                     NULL);
804 }
805
806
807 /**
808  * Main function
809  */
810 int
811 main (int argc, char **argv)
812 {
813   char *const argv2[] = { "test_testbed_api_controllerlink",
814     "-c", "test_testbed_api.conf",
815     NULL
816   };
817   struct GNUNET_GETOPT_CommandLineOption options[] = {
818     GNUNET_GETOPT_OPTION_END
819   };
820   int ret;
821
822   result = INIT;
823   ret =
824       GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
825                           "test_testbed_api_controllerlink", "nohelp", options,
826                           &run, NULL);
827   if (GNUNET_OK != ret)
828     return 1;
829   switch (result)
830   {
831   case SUCCESS:
832     return 0;
833   case SKIP:
834     return 77;                  /* Mark test as skipped */
835   default:
836     return 1;
837   }
838 }
839
840 /* end of test_testbed_api_controllerlink.c */