peer destroy with new operations handling
[oweals/gnunet.git] / src / testbed / test_testbed_api_2peers.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_2peers.c
23  * @brief testcases for the testbed api: 2 peers are configured, started and
24  *          connected together
25  * @author Sree Harsha Totakura
26  */
27
28 #include "platform.h"
29 #include "gnunet_util_lib.h"
30 #include "gnunet_testing_lib-new.h"
31 #include "gnunet_testbed_service.h"
32
33
34 /**
35  * Generic logging shortcut
36  */
37 #define LOG(kind,...)                           \
38   GNUNET_log (kind, __VA_ARGS__)
39
40 /**
41  * Relative time seconds shorthand
42  */
43 #define TIME_REL_SECS(sec) \
44   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, sec)
45
46 /**
47  * Our localhost
48  */
49 static struct GNUNET_TESTBED_Host *host;
50
51 /**
52  * The controller process
53  */
54 static struct GNUNET_TESTBED_ControllerProc *cp;
55
56 /**
57  * The controller handle
58  */
59 static struct GNUNET_TESTBED_Controller *controller;
60
61 /**
62  * A neighbouring host
63  */
64 static struct GNUNET_TESTBED_Host *neighbour;
65
66 /**
67  * Handle for neighbour registration
68  */
69 static struct GNUNET_TESTBED_HostRegistrationHandle *reg_handle;
70
71 /**
72  * Handle for a peer
73  */
74 static struct GNUNET_TESTBED_Peer *peer;
75
76 /**
77  * Handle to configuration
78  */
79 static struct GNUNET_CONFIGURATION_Handle *cfg;
80
81 /**
82  * Handle to operation
83  */
84 static struct GNUNET_TESTBED_Operation *operation;
85
86 /**
87  * Abort task identifier
88  */
89 static GNUNET_SCHEDULER_TaskIdentifier abort_task;
90
91 /**
92  * The testing result
93  */
94 static int result;
95
96
97 /**
98  * Shutdown nicely
99  *
100  * @param cls NULL
101  * @param tc the task context
102  */
103 static void
104 do_shutdown (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc)
105 {
106   if (GNUNET_SCHEDULER_NO_TASK != abort_task)
107     GNUNET_SCHEDULER_cancel (abort_task);
108   if (NULL != reg_handle)
109     GNUNET_TESTBED_cancel_registration (reg_handle);
110   GNUNET_TESTBED_controller_disconnect (controller);
111   GNUNET_CONFIGURATION_destroy (cfg);
112   if (NULL != cp)
113     GNUNET_TESTBED_controller_stop (cp);
114   GNUNET_TESTBED_host_destroy (neighbour);
115   GNUNET_TESTBED_host_destroy (host);
116 }
117
118
119 /**
120  * abort task to run on test timed out
121  *
122  * @param cls NULL
123  * @param tc the task context
124  */
125 static void
126 do_abort (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc)
127 {
128   LOG (GNUNET_ERROR_TYPE_WARNING, "Test timedout -- Aborting\n");
129   abort_task = GNUNET_SCHEDULER_NO_TASK;
130   do_shutdown (cls, tc);
131 }
132
133
134 /**
135  * Signature of the event handler function called by the
136  * respective event controller.
137  *
138  * @param cls closure
139  * @param event information about the event
140  */
141 static void 
142 controller_cb(void *cls, const struct GNUNET_TESTBED_EventInformation *event)
143 {
144   GNUNET_assert (GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type);
145   GNUNET_assert (event->details.operation_finished.operation == operation);
146   GNUNET_assert (NULL == event->details.operation_finished.op_cls);
147   GNUNET_assert (NULL == event->details.operation_finished.emsg);
148   GNUNET_assert (GNUNET_TESTBED_PIT_GENERIC ==
149                  event->details.operation_finished.pit);
150   GNUNET_assert (NULL == event->details.operation_finished.op_result.generic);
151   result = GNUNET_YES;  
152   GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
153 }
154
155
156 /**
157  * Functions of this signature are called when a peer has been successfully
158  * created
159  *
160  * @param cls the closure from GNUNET_TESTBED_peer_create()
161  * @param peer the handle for the created peer; NULL on any error during
162  *          creation
163  * @param emsg NULL if peer is not NULL; else MAY contain the error description
164  */
165 static void
166 peer_create_cb (void *cls,
167                 struct GNUNET_TESTBED_Peer *peer, const char *emsg)
168 {
169   struct GNUNET_TESTBED_Peer **peer_ptr;
170   
171   peer_ptr = cls;
172   GNUNET_assert (NULL != peer);
173   GNUNET_assert (NULL != peer_ptr);
174   *peer_ptr = peer;
175   operation = GNUNET_TESTBED_peer_destroy (peer);
176   GNUNET_assert (NULL != operation);
177 }
178
179
180 /**
181  * Callback which will be called to after a host registration succeeded or failed
182  *
183  * @param cls the host which has been registered
184  * @param emsg the error message; NULL if host registration is successful
185  */
186 static void 
187 registration_comp (void *cls, const char *emsg)
188 {
189   GNUNET_assert (cls == neighbour);
190   reg_handle = NULL;  
191   operation = GNUNET_TESTBED_peer_create (controller, host, cfg, &peer_create_cb, &peer);
192   GNUNET_assert (NULL != operation);
193 }
194
195
196 /**
197  * Callback to signal successfull startup of the controller process
198  *
199  * @param cls the closure from GNUNET_TESTBED_controller_start()
200  * @param cfg the configuration with which the controller has been started;
201  *          NULL if status is not GNUNET_OK
202  * @param status GNUNET_OK if the startup is successfull; GNUNET_SYSERR if not,
203  *          GNUNET_TESTBED_controller_stop() shouldn't be called in this case
204  */
205 static void 
206 status_cb (void *cls, 
207            const struct GNUNET_CONFIGURATION_Handle *cfg, int status)
208 {
209   uint64_t event_mask;
210
211   GNUNET_assert (GNUNET_OK == status);
212   event_mask = 0;
213   event_mask |= (1L << GNUNET_TESTBED_ET_PEER_START);
214   event_mask |= (1L << GNUNET_TESTBED_ET_PEER_STOP);
215   event_mask |= (1L << GNUNET_TESTBED_ET_CONNECT);
216   event_mask |= (1L << GNUNET_TESTBED_ET_OPERATION_FINISHED);
217   controller = GNUNET_TESTBED_controller_connect (cfg, host, event_mask,
218                                                   &controller_cb, NULL);
219   GNUNET_assert (NULL != controller);
220   neighbour = GNUNET_TESTBED_host_create ("localhost", NULL, 0);
221   GNUNET_assert (NULL != neighbour);
222   reg_handle = 
223     GNUNET_TESTBED_register_host (controller, neighbour, &registration_comp,
224                                   neighbour);
225   GNUNET_assert (NULL != reg_handle);
226 }
227
228
229
230 /**
231  * Main run function. 
232  *
233  * @param cls NULL
234  * @param args arguments passed to GNUNET_PROGRAM_run
235  * @param cfgfile the path to configuration file
236  * @param cfg the configuration file handle
237  */
238 static void
239 run (void *cls, char *const *args, const char *cfgfile,
240      const struct GNUNET_CONFIGURATION_Handle *config)
241 {
242   host = GNUNET_TESTBED_host_create (NULL, NULL, 0);
243   GNUNET_assert (NULL != host);
244   cfg = GNUNET_CONFIGURATION_dup (config);
245   cp = GNUNET_TESTBED_controller_start ("127.0.0.1", host, cfg, status_cb, NULL);
246   abort_task = GNUNET_SCHEDULER_add_delayed 
247     (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5), &do_abort, NULL);
248 }
249
250
251 /**
252  * Main function
253  */
254 int main (int argc, char **argv)
255 {
256   int ret;
257
258   char *const argv2[] = { "test_testbed_api",
259                           "-c", "test_testbed_api.conf",
260                           NULL
261   };
262   struct GNUNET_GETOPT_CommandLineOption options[] = {
263     GNUNET_GETOPT_OPTION_END
264   };
265   result = GNUNET_SYSERR;
266   ret = GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
267                             "test_testbed_api", "nohelp", options, &run,
268                             NULL);
269   if ((GNUNET_OK != ret) || (GNUNET_OK != result))
270     return 1;
271   return 0;
272 }