bda27d8cf305e05b90d01df88e56518be9e5571d
[oweals/gnunet.git] / src / testbed / test_testbed_api_controllerlink.c
1 /*
2       This file is part of GNUnet
3       (C) 2008--2012 Christian Grothoff (and other contributing authors)
4
5       GNUnet is free software; you can redistribute it and/or modify
6       it under the terms of the GNU General Public License as published
7       by the Free Software Foundation; either version 3, or (at your
8       option) any later version.
9
10       GNUnet is distributed in the hope that it will be useful, but
11       WITHOUT ANY WARRANTY; without even the implied warranty of
12       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13       General Public License for more details.
14
15       You should have received a copy of the GNU General Public License
16       along with GNUnet; see the file COPYING.  If not, write to the
17       Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18       Boston, MA 02111-1307, USA.
19  */
20
21 /**
22  * @file testbed/test_testbed_api_controllerlink.c
23  * @brief testcase for testing controller to subcontroller linking
24  * @author Sree Harsha Totakura <sreeharsha@totakura.in> 
25  */
26
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_testing_lib-new.h"
30 #include "gnunet_testbed_service.h"
31
32 /**
33  * Generic logging shortcut
34  */
35 #define LOG(kind,...)                           \
36   GNUNET_log (kind, __VA_ARGS__)
37
38 /**
39  * Debug logging shorthand
40  */
41 #define LOG_DEBUG(...)                          \
42   LOG(GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
43
44 /**
45  * Different stages in testing
46  */
47 enum Stage
48   {
49
50     /**
51      * Initial stage
52      */
53     INIT,
54
55     /**
56      * Master controller has started
57      */
58     MASTER_STARTED,
59
60     /**
61      * The first slave has been registered at master controller
62      */
63     SLAVE1_REGISTERED,
64
65     /**
66      * Final stage
67      */
68     SUCCESS
69
70   };
71
72 /**
73  * Host for running master controller
74  */
75 static struct GNUNET_TESTBED_Host *host;
76
77 /**
78  * The master controller process
79  */
80 static struct GNUNET_TESTBED_ControllerProc *cp;
81
82 /**
83  * Handle to master controller
84  */
85 static struct GNUNET_TESTBED_Controller *mc;
86
87 /**
88  * Slave host for running slave controller
89  */
90 static struct GNUNET_TESTBED_Host *slave;
91
92 /**
93  * Slave host registration handle
94  */
95 static struct GNUNET_TESTBED_HostRegistrationHandle *rh;
96
97 /**
98  * Handle to global configuration
99  */
100 static struct GNUNET_CONFIGURATION_Handle *cfg;
101
102 /**
103  * Abort task
104  */
105 static GNUNET_SCHEDULER_TaskIdentifier abort_task;
106
107 /**
108  * Event mask
109  */
110 uint64_t event_mask;
111
112 /**
113  * Global testing status
114  */
115 static enum Stage result;
116
117
118 /**
119  * Shutdown nicely
120  *
121  * @param cls NULL
122  * @param tc the task context
123  */
124 static void
125 do_shutdown (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc)
126 {
127   if (GNUNET_SCHEDULER_NO_TASK != abort_task)
128     GNUNET_SCHEDULER_cancel (abort_task);
129     if (NULL != slave)
130     GNUNET_TESTBED_host_destroy (slave);
131   if (NULL != host)
132     GNUNET_TESTBED_host_destroy (host);
133   if (NULL != mc)
134     GNUNET_TESTBED_controller_disconnect (mc);
135   if (NULL != cfg)
136     GNUNET_CONFIGURATION_destroy (cfg);
137   if (NULL != cp)
138     GNUNET_TESTBED_controller_stop (cp);
139   if (NULL != rh)
140     GNUNET_TESTBED_cancel_registration (rh);
141   
142 }
143
144
145 /**
146  * abort task to run on test timed out
147  *
148  * @param cls NULL
149  * @param tc the task context
150  */
151 static void
152 do_abort (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc)
153 {
154   LOG (GNUNET_ERROR_TYPE_WARNING, "Test timedout -- Aborting\n");
155   abort_task = GNUNET_SCHEDULER_NO_TASK;
156   do_shutdown (cls, tc);
157 }
158
159
160 /**
161  * Signature of the event handler function called by the
162  * respective event controller.
163  *
164  * @param cls closure
165  * @param event information about the event
166  */
167 static void 
168 controller_cb(void *cls, const struct GNUNET_TESTBED_EventInformation *event)
169 {
170   GNUNET_assert (0);
171 }
172
173
174 /**
175  * Callback which will be called to after a host registration succeeded or failed
176  *
177  * @param cls the host which has been registered
178  * @param emsg the error message; NULL if host registration is successful
179  */
180 static void 
181 registration_cont (void *cls, const char *emsg)
182 {
183   rh = NULL;
184   switch (result)
185   {
186   case MASTER_STARTED:
187     GNUNET_assert (NULL == emsg);
188     GNUNET_assert (NULL != mc);
189     result = SLAVE1_REGISTERED;
190     GNUNET_assert (NULL != cfg);
191     GNUNET_TESTBED_controller_link (mc, slave, NULL, cfg, GNUNET_YES);
192     result = SUCCESS;
193     GNUNET_SCHEDULER_add_delayed 
194       (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10),
195        &do_shutdown, NULL);
196     break;
197   case INIT:
198   case SUCCESS:
199   case SLAVE1_REGISTERED:
200     GNUNET_assert (0);
201   }
202 }
203
204 /**
205  * Callback to signal successfull startup of the controller process
206  *
207  * @param cls the closure from GNUNET_TESTBED_controller_start()
208  * @param cfg the configuration with which the controller has been started;
209  *          NULL if status is not GNUNET_OK
210  * @param status GNUNET_OK if the startup is successfull; GNUNET_SYSERR if not,
211  *          GNUNET_TESTBED_controller_stop() shouldn't be called in this case
212  */
213 static void 
214 status_cb (void *cls, 
215            const struct GNUNET_CONFIGURATION_Handle *config, int status)
216 {
217   switch (result)
218   {
219   case INIT:
220     GNUNET_assert (GNUNET_OK == status);
221     event_mask = 0;
222     event_mask |= (1L << GNUNET_TESTBED_ET_PEER_START);
223     event_mask |= (1L << GNUNET_TESTBED_ET_PEER_STOP);
224     event_mask |= (1L << GNUNET_TESTBED_ET_CONNECT);
225     event_mask |= (1L << GNUNET_TESTBED_ET_OPERATION_FINISHED);
226     mc = GNUNET_TESTBED_controller_connect (config, host, event_mask,
227                                             &controller_cb, NULL);
228     GNUNET_assert (NULL != mc);
229     result = MASTER_STARTED;
230     slave = GNUNET_TESTBED_host_create_with_id (2, "127.0.0.1", NULL, 0);
231     GNUNET_assert (NULL != slave);
232     rh = GNUNET_TESTBED_register_host (mc, slave, &registration_cont, NULL);
233     GNUNET_assert (NULL != rh);
234     break;
235   default:
236     GNUNET_assert (0);
237   }
238 }
239
240
241 /**
242  * Main run function. 
243  *
244  * @param cls NULL
245  * @param args arguments passed to GNUNET_PROGRAM_run
246  * @param cfgfile the path to configuration file
247  * @param cfg the configuration file handle
248  */
249 static void
250 run (void *cls, char *const *args, const char *cfgfile,
251      const struct GNUNET_CONFIGURATION_Handle *config)
252 {
253   host = GNUNET_TESTBED_host_create (NULL, NULL, 0);
254   GNUNET_assert (NULL != host);
255   cfg = GNUNET_CONFIGURATION_dup (config);
256   cp =
257     GNUNET_TESTBED_controller_start ("127.0.0.1", host, cfg, status_cb, NULL);
258   abort_task = GNUNET_SCHEDULER_add_delayed 
259     (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 30), 
260      &do_abort, NULL);
261 }
262
263
264 /**
265  * Main function
266  */
267 int main (int argc, char **argv)
268 {
269   int ret;
270
271   char *const argv2[] = { "test_testbed_api_controllerlink",
272                           "-c", "test_testbed_api.conf",
273                           NULL
274   };
275   struct GNUNET_GETOPT_CommandLineOption options[] = {
276     GNUNET_GETOPT_OPTION_END
277   };
278   result = INIT;
279   ret = GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
280                             "test_testbed_api_controllerlink", "nohelp", options, &run,
281                             NULL);
282   if ((GNUNET_OK != ret) || (SUCCESS != result))
283     return 1;
284   return 0;
285 }