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