- adapt testcases to new api
[oweals/gnunet.git] / src / mesh / test_mesh_local.c
1 /*
2      This file is part of GNUnet.
3      (C) 2011 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 mesh/test_mesh_local.c
23  * @brief test mesh local: test of mesh tunnels with just one peer
24  * @author Bartlomiej Polot
25  */
26
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_dht_service.h"
30 #include "gnunet_testing_lib.h"
31 #include "gnunet_mesh_service.h"
32
33 struct GNUNET_TESTING_Peer *me;
34
35 static struct GNUNET_MESH_Handle *mesh_peer_1;
36
37 static struct GNUNET_MESH_Handle *mesh_peer_2;
38
39 static struct GNUNET_MESH_Tunnel *t;
40
41 static int result = GNUNET_OK;
42
43 static GNUNET_SCHEDULER_TaskIdentifier abort_task;
44
45 static GNUNET_SCHEDULER_TaskIdentifier shutdown_task;
46
47
48 /**
49  * Shutdown nicely
50  */
51 static void
52 do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
53 {
54   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shutdown\n");
55   if (GNUNET_SCHEDULER_NO_TASK != abort_task)
56   {
57     GNUNET_SCHEDULER_cancel (abort_task);
58   }
59   if (NULL != t)
60   {
61     GNUNET_MESH_tunnel_destroy (t);
62   }
63   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnect client 1\n");
64   if (NULL != mesh_peer_1)
65   {
66     GNUNET_MESH_disconnect (mesh_peer_1);
67   }
68   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnect client 2\n");
69   if (NULL != mesh_peer_2)
70   {
71     GNUNET_MESH_disconnect (mesh_peer_2);
72   }
73 }
74
75
76 /**
77  * Something went wrong and timed out. Kill everything and set error flag
78  */
79 static void
80 do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
81 {
82   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ABORT\n");
83   result = GNUNET_SYSERR;
84   abort_task = GNUNET_SCHEDULER_NO_TASK;
85   if (GNUNET_SCHEDULER_NO_TASK != shutdown_task)
86   {
87     GNUNET_SCHEDULER_cancel (shutdown_task);
88     shutdown_task = GNUNET_SCHEDULER_NO_TASK;
89   }
90   do_shutdown (cls, tc);
91 }
92
93
94 /**
95  * Function is called whenever a message is received.
96  *
97  * @param cls closure (set from GNUNET_MESH_connect)
98  * @param tunnel connection to the other end
99  * @param tunnel_ctx place to store local state associated with the tunnel
100  * @param message the actual message
101  * 
102  * @return GNUNET_OK to keep the connection open,
103  *         GNUNET_SYSERR to close it (signal serious error)
104  */
105 static int
106 data_callback (void *cls, struct GNUNET_MESH_Tunnel *tunnel, void **tunnel_ctx,
107                const struct GNUNET_MessageHeader *message)
108 {
109   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Data callback! Shutting down.\n");
110   if (GNUNET_SCHEDULER_NO_TASK != shutdown_task)
111     GNUNET_SCHEDULER_cancel (shutdown_task);
112   shutdown_task =
113     GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &do_shutdown,
114                                   NULL);
115   GNUNET_MESH_receive_done (tunnel);
116   return GNUNET_OK;
117 }
118
119
120 /**
121  * Method called whenever another peer has added us to a tunnel
122  * the other peer initiated.
123  *
124  * @param cls closure
125  * @param tunnel new handle to the tunnel
126  * @param initiator peer that started the tunnel
127  * @param port port number
128  * @return initial tunnel context for the tunnel (can be NULL -- that's not an error)
129  */
130 static void *
131 inbound_tunnel (void *cls, struct GNUNET_MESH_Tunnel *tunnel,
132                 const struct GNUNET_PeerIdentity *initiator,
133                 uint32_t port)
134 {
135   long id = (long) cls;
136
137   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
138               "received incoming tunnel on peer %d, port %u\n",
139               id, port);
140   if (id != 2L)
141   {
142     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
143                 "wrong peer\n");
144     result = GNUNET_SYSERR;
145   }
146   return NULL;
147 }
148
149
150 /**
151  * Function called whenever an inbound tunnel is destroyed.  Should clean up
152  * any associated state.
153  *
154  * @param cls closure (set from GNUNET_MESH_connect)
155  * @param tunnel connection to the other end (henceforth invalid)
156  * @param tunnel_ctx place where local state associated
157  *                   with the tunnel is stored
158  */
159 static void
160 inbound_end (void *cls, const struct GNUNET_MESH_Tunnel *tunnel,
161              void *tunnel_ctx)
162 {
163   long id = (long) cls;
164
165   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
166               "incoming tunnel closed at peer %ld\n",
167               id);
168 }
169
170
171 /**
172  * Handler array for traffic received on peer1
173  */
174 static struct GNUNET_MESH_MessageHandler handlers1[] = {
175   {&data_callback, 1, 0},
176   {NULL, 0, 0}
177 };
178
179
180 /**
181  * Handler array for traffic received on peer2 (none expected)
182  */
183 static struct GNUNET_MESH_MessageHandler handlers2[] = {
184   {&data_callback, 1, 0},
185   {NULL, 0, 0}
186 };
187
188
189 /**
190  * Data send callback: fillbuffer with test packet.
191  * 
192  * @param cls Closure (unused).
193  * @param size Buffer size.
194  * @param buf Buffer to fill.
195  * 
196  * @return size of test packet.
197  */
198 static size_t
199 do_send (void *cls, size_t size, void *buf)
200 {
201   struct GNUNET_MessageHeader *m = buf;
202
203   if (NULL == buf)
204   {
205     GNUNET_break (0);
206     result = GNUNET_SYSERR;
207     return 0;
208   }
209   m->size = htons (sizeof (struct GNUNET_MessageHeader));
210   m->type = htons (1);
211   GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader));
212   return sizeof (struct GNUNET_MessageHeader);
213 }
214
215 /**
216  * Connect to other client and send data
217  * 
218  * @param cls Closue (unused).
219  * @param tc TaskContext.
220  */
221 static void
222 do_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
223 {
224   struct GNUNET_PeerIdentity id;
225
226   GNUNET_TESTING_peer_get_identity (me, &id);
227   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CONNECT BY PORT\n");
228   t = GNUNET_MESH_tunnel_create (mesh_peer_1, NULL, &id, 1, GNUNET_YES, GNUNET_NO);
229   GNUNET_MESH_notify_transmit_ready (t, GNUNET_NO,
230                                      GNUNET_TIME_UNIT_FOREVER_REL,
231                                      sizeof (struct GNUNET_MessageHeader),
232                                      &do_send, NULL);
233 }
234
235
236 /**
237  * Initialize framework and start test
238  * 
239  * @param cls Closure (unused).
240  * @param cfg Configuration handle.
241  * @param peer Testing peer handle.
242  */
243 static void
244 run (void *cls, 
245      const struct GNUNET_CONFIGURATION_Handle *cfg,
246      struct GNUNET_TESTING_Peer *peer)
247 {
248   static uint32_t ports[] = {1, 0};
249
250   me = peer;
251   abort_task =
252       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
253                                     (GNUNET_TIME_UNIT_SECONDS, 15), &do_abort,
254                                     NULL);
255   mesh_peer_1 = GNUNET_MESH_connect (cfg,       /* configuration */
256                                      (void *) 1L,     /* cls */
257                                      &inbound_tunnel,   /* inbound new hndlr */
258                                      &inbound_end,      /* inbound end hndlr */
259                                      handlers1, /* traffic handlers */
260                                      NULL);     /* ports offered */
261
262   mesh_peer_2 = GNUNET_MESH_connect (cfg,       /* configuration */
263                                      (void *) 2L,     /* cls */
264                                      &inbound_tunnel,   /* inbound new hndlr */
265                                      &inbound_end,      /* inbound end hndlr */
266                                      handlers2, /* traffic handlers */
267                                      ports);     /* ports offered */
268   if (NULL == mesh_peer_1 || NULL == mesh_peer_2)
269   {
270     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Couldn't connect to mesh :(\n");
271     result = GNUNET_SYSERR;
272     return;
273   }
274   else
275   {
276     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "YAY! CONNECTED TO MESH :D\n");
277   }
278   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &do_connect, NULL);
279 }
280
281
282 /**
283  * Main
284  */
285 int
286 main (int argc, char *argv[])
287 {
288   if (0 != GNUNET_TESTING_peer_run ("test-mesh-local",
289                                     "test_mesh.conf",
290                                 &run, NULL))
291   {
292     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "run failed\n");
293     return 2;
294   }
295   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Final result: %d\n", result);
296   return (result == GNUNET_OK) ? 0 : 1;
297 }
298
299 /* end of test_mesh_local_1.c */