06b0b80292f75f58ec7c9d96a54409fff60024df
[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  * Operation handle for linking controllers
109  */
110 static struct GNUNET_TESTBED_Operation *op;
111
112 /**
113  * Event mask
114  */
115 uint64_t event_mask;
116
117 /**
118  * Global testing status
119  */
120 static enum Stage result;
121
122
123 /**
124  * Shutdown nicely
125  *
126  * @param cls NULL
127  * @param tc the task context
128  */
129 static void
130 do_shutdown (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc)
131 {
132   if (GNUNET_SCHEDULER_NO_TASK != abort_task)
133     GNUNET_SCHEDULER_cancel (abort_task);
134     if (NULL != slave)
135     GNUNET_TESTBED_host_destroy (slave);
136   if (NULL != host)
137     GNUNET_TESTBED_host_destroy (host);
138   if (NULL != mc)
139     GNUNET_TESTBED_controller_disconnect (mc);
140   if (NULL != cfg)
141     GNUNET_CONFIGURATION_destroy (cfg);
142   if (NULL != cp)
143     GNUNET_TESTBED_controller_stop (cp);
144   if (NULL != rh)
145     GNUNET_TESTBED_cancel_registration (rh);
146   
147 }
148
149
150 /**
151  * abort task to run on test timed out
152  *
153  * @param cls NULL
154  * @param tc the task context
155  */
156 static void
157 do_abort (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc)
158 {
159   LOG (GNUNET_ERROR_TYPE_WARNING, "Test timedout -- Aborting\n");
160   abort_task = GNUNET_SCHEDULER_NO_TASK;
161   do_shutdown (cls, tc);
162 }
163
164
165 /**
166  * Signature of the event handler function called by the
167  * respective event controller.
168  *
169  * @param cls closure
170  * @param event information about the event
171  */
172 static void 
173 controller_cb(void *cls, const struct GNUNET_TESTBED_EventInformation *event)
174 {
175   switch (result)
176   {
177   case SLAVE1_REGISTERED:
178     GNUNET_assert (NULL != event);
179     GNUNET_assert (GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type);
180     GNUNET_assert (event->details.operation_finished.operation == op);
181     GNUNET_assert (NULL == event->details.operation_finished.op_cls);
182     GNUNET_assert (NULL == event->details.operation_finished.emsg);
183     GNUNET_assert (GNUNET_TESTBED_PIT_GENERIC ==
184                    event->details.operation_finished.pit);
185     GNUNET_assert (NULL == event->details.operation_finished.op_result.generic);
186     GNUNET_TESTBED_operation_done (op);
187     op = NULL;
188     result = SUCCESS;
189     GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
190     break;
191   default:
192     GNUNET_assert (0);
193   }
194 }
195
196
197 /**
198  * Callback which will be called to after a host registration succeeded or failed
199  *
200  * @param cls the host which has been registered
201  * @param emsg the error message; NULL if host registration is successful
202  */
203 static void 
204 registration_cont (void *cls, const char *emsg)
205 {
206   rh = NULL;
207   switch (result)
208   {
209   case MASTER_STARTED:
210     GNUNET_assert (NULL == emsg);
211     GNUNET_assert (NULL != mc);
212     result = SLAVE1_REGISTERED;
213     GNUNET_assert (NULL != cfg);
214     op = GNUNET_TESTBED_controller_link (mc, slave, NULL, cfg, GNUNET_YES);
215     GNUNET_assert (NULL != op);
216     break;
217   case INIT:
218   case SUCCESS:
219   case SLAVE1_REGISTERED:
220     GNUNET_assert (0);
221   }
222 }
223
224 /**
225  * Callback to signal successfull startup of the controller process
226  *
227  * @param cls the closure from GNUNET_TESTBED_controller_start()
228  * @param cfg the configuration with which the controller has been started;
229  *          NULL if status is not GNUNET_OK
230  * @param status GNUNET_OK if the startup is successfull; GNUNET_SYSERR if not,
231  *          GNUNET_TESTBED_controller_stop() shouldn't be called in this case
232  */
233 static void 
234 status_cb (void *cls, 
235            const struct GNUNET_CONFIGURATION_Handle *config, int status)
236 {
237   switch (result)
238   {
239   case INIT:
240     GNUNET_assert (GNUNET_OK == status);
241     event_mask = 0;
242     event_mask |= (1L << GNUNET_TESTBED_ET_PEER_START);
243     event_mask |= (1L << GNUNET_TESTBED_ET_PEER_STOP);
244     event_mask |= (1L << GNUNET_TESTBED_ET_CONNECT);
245     event_mask |= (1L << GNUNET_TESTBED_ET_OPERATION_FINISHED);
246     mc = GNUNET_TESTBED_controller_connect (config, host, event_mask,
247                                             &controller_cb, NULL);
248     GNUNET_assert (NULL != mc);
249     result = MASTER_STARTED;
250     slave = GNUNET_TESTBED_host_create_with_id (2, "127.0.0.1", NULL, 0);
251     GNUNET_assert (NULL != slave);
252     rh = GNUNET_TESTBED_register_host (mc, slave, &registration_cont, NULL);
253     GNUNET_assert (NULL != rh);
254     break;
255   default:
256     GNUNET_assert (0);
257   }
258 }
259
260
261 /**
262  * Main run function. 
263  *
264  * @param cls NULL
265  * @param args arguments passed to GNUNET_PROGRAM_run
266  * @param cfgfile the path to configuration file
267  * @param cfg the configuration file handle
268  */
269 static void
270 run (void *cls, char *const *args, const char *cfgfile,
271      const struct GNUNET_CONFIGURATION_Handle *config)
272 {
273   host = GNUNET_TESTBED_host_create (NULL, NULL, 0);
274   GNUNET_assert (NULL != host);
275   cfg = GNUNET_CONFIGURATION_dup (config);
276   cp =
277     GNUNET_TESTBED_controller_start ("127.0.0.1", host, cfg, status_cb, NULL);
278   abort_task = GNUNET_SCHEDULER_add_delayed 
279     (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5), 
280      &do_abort, NULL);
281 }
282
283
284 /**
285  * Main function
286  */
287 int main (int argc, char **argv)
288 {
289   int ret;
290
291   char *const argv2[] = { "test_testbed_api_controllerlink",
292                           "-c", "test_testbed_api.conf",
293                           NULL
294   };
295   struct GNUNET_GETOPT_CommandLineOption options[] = {
296     GNUNET_GETOPT_OPTION_END
297   };
298   result = INIT;
299   ret = GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
300                             "test_testbed_api_controllerlink", "nohelp", options, &run,
301                             NULL);
302   if ((GNUNET_OK != ret) || (SUCCESS != result))
303     return 1;
304   return 0;
305 }