aboutsummaryrefslogtreecommitdiff
path: root/src/mesh
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2011-10-20 14:10:28 +0000
committerBart Polot <bart@net.in.tum.de>2011-10-20 14:10:28 +0000
commit9aa7853d6c5fa43d0384ae79476bb45242af61fb (patch)
tree8d81c58b5687bf52b2bf80f0f53826f3a0c5c782 /src/mesh
parent85e2435610b558e583f10eb6fe5a8f73d7aab3a7 (diff)
downloadgnunet-9aa7853d6c5fa43d0384ae79476bb45242af61fb.tar.gz
gnunet-9aa7853d6c5fa43d0384ae79476bb45242af61fb.zip
Changed testcases structure
Diffstat (limited to 'src/mesh')
-rw-r--r--src/mesh/Makefile.am21
-rw-r--r--src/mesh/gnunet-service-mesh.c7
-rw-r--r--src/mesh/test_mesh_small.c510
-rw-r--r--src/mesh/test_mesh_small_multicast.c776
-rw-r--r--src/mesh/test_mesh_small_unicast.c785
5 files changed, 449 insertions, 1650 deletions
diff --git a/src/mesh/Makefile.am b/src/mesh/Makefile.am
index 2c4dc0b4c..4e7e5c323 100644
--- a/src/mesh/Makefile.am
+++ b/src/mesh/Makefile.am
@@ -54,7 +54,6 @@ check_PROGRAMS = \
54 test_mesh_path_api \ 54 test_mesh_path_api \
55 test_mesh_local_1 \ 55 test_mesh_local_1 \
56 test_mesh_local_2 \ 56 test_mesh_local_2 \
57 test_mesh_small \
58 test_mesh_small_unicast \ 57 test_mesh_small_unicast \
59 test_mesh_small_unicast_far \ 58 test_mesh_small_unicast_far \
60 test_mesh_small_multicast 59 test_mesh_small_multicast
@@ -93,17 +92,8 @@ test_mesh_local_2_LDADD = \
93test_mesh_local_2_DEPENDENCIES = \ 92test_mesh_local_2_DEPENDENCIES = \
94 libgnunetmeshnew.la 93 libgnunetmeshnew.la
95 94
96test_mesh_small_SOURCES = \
97 test_mesh_small.c
98test_mesh_small_LDADD = \
99 $(top_builddir)/src/mesh/libgnunetmeshnew.la \
100 $(top_builddir)/src/util/libgnunetutil.la \
101 $(top_builddir)/src/testing/libgnunettesting.la
102test_mesh_small_DEPENDENCIES = \
103 libgnunetmeshnew.la
104
105test_mesh_small_unicast_SOURCES = \ 95test_mesh_small_unicast_SOURCES = \
106 test_mesh_small_unicast.c 96 test_mesh_small.c
107test_mesh_small_unicast_LDADD = \ 97test_mesh_small_unicast_LDADD = \
108 $(top_builddir)/src/mesh/libgnunetmeshnew.la \ 98 $(top_builddir)/src/mesh/libgnunetmeshnew.la \
109 $(top_builddir)/src/util/libgnunetutil.la \ 99 $(top_builddir)/src/util/libgnunetutil.la \
@@ -112,7 +102,7 @@ test_mesh_small_unicast_DEPENDENCIES = \
112 libgnunetmeshnew.la 102 libgnunetmeshnew.la
113 103
114test_mesh_small_unicast_far_SOURCES = \ 104test_mesh_small_unicast_far_SOURCES = \
115 test_mesh_small_unicast_far.c 105 test_mesh_small.c
116test_mesh_small_unicast_far_LDADD = \ 106test_mesh_small_unicast_far_LDADD = \
117 $(top_builddir)/src/mesh/libgnunetmeshnew.la \ 107 $(top_builddir)/src/mesh/libgnunetmeshnew.la \
118 $(top_builddir)/src/util/libgnunetutil.la \ 108 $(top_builddir)/src/util/libgnunetutil.la \
@@ -121,7 +111,7 @@ test_mesh_small_unicast_far_DEPENDENCIES = \
121 libgnunetmeshnew.la 111 libgnunetmeshnew.la
122 112
123test_mesh_small_multicast_SOURCES = \ 113test_mesh_small_multicast_SOURCES = \
124 test_mesh_small_multicast.c 114 test_mesh_small.c
125test_mesh_small_multicast_LDADD = \ 115test_mesh_small_multicast_LDADD = \
126 $(top_builddir)/src/mesh/libgnunetmeshnew.la \ 116 $(top_builddir)/src/mesh/libgnunetmeshnew.la \
127 $(top_builddir)/src/util/libgnunetutil.la \ 117 $(top_builddir)/src/util/libgnunetutil.la \
@@ -131,9 +121,10 @@ test_mesh_small_multicast_DEPENDENCIES = \
131 121
132 122
133if ENABLE_TEST_RUN 123if ENABLE_TEST_RUN
134TESTS = test_mesh_api test_mesh_path_api test_mesh_local_1 test_mesh_local_2 test_mesh_small test_mesh_small_unicast 124TESTS = test_mesh_api test_mesh_path_api test_mesh_local_1 test_mesh_local_2 test_mesh_small_unicast test_mesh_small_multicast
135endif 125endif
136 126
137EXTRA_DIST = \ 127EXTRA_DIST = \
138 test_mesh.conf \ 128 test_mesh.conf \
139 test_mesh_path.conf \ No newline at end of file 129 test_mesh_path.conf \
130 test_mesh_small.conf \ No newline at end of file
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c
index 3108d9149..0f2bbe3cf 100644
--- a/src/mesh/gnunet-service-mesh.c
+++ b/src/mesh/gnunet-service-mesh.c
@@ -4241,17 +4241,12 @@ main (int argc, char *const *argv)
4241{ 4241{
4242 int ret; 4242 int ret;
4243 4243
4244#if MESH_DEBUG
4245// fprintf (stderr, "main ()\n");
4246#endif
4247 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: main()\n"); 4244 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: main()\n");
4248 ret = 4245 ret =
4249 (GNUNET_OK == 4246 (GNUNET_OK ==
4250 GNUNET_SERVICE_run (argc, argv, "mesh", GNUNET_SERVICE_OPTION_NONE, &run, 4247 GNUNET_SERVICE_run (argc, argv, "mesh", GNUNET_SERVICE_OPTION_NONE, &run,
4251 NULL)) ? 0 : 1; 4248 NULL)) ? 0 : 1;
4252 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: main() END\n"); 4249 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: main() END\n");
4253#if MESH_DEBUG 4250
4254// fprintf (stderr, "main () END\n");
4255#endif
4256 return ret; 4251 return ret;
4257} 4252}
diff --git a/src/mesh/test_mesh_small.c b/src/mesh/test_mesh_small.c
index a7ea4ee79..9fe2c1292 100644
--- a/src/mesh/test_mesh_small.c
+++ b/src/mesh/test_mesh_small.c
@@ -20,7 +20,7 @@
20/** 20/**
21 * @file mesh/test_mesh_small.c 21 * @file mesh/test_mesh_small.c
22 * 22 *
23 * @brief Test for the mesh service. 23 * @brief Test for the mesh service: retransmission of traffic.
24 */ 24 */
25#include "platform.h" 25#include "platform.h"
26#include "gnunet_testing_lib.h" 26#include "gnunet_testing_lib.h"
@@ -47,15 +47,31 @@ struct StatsContext
47}; 47};
48 48
49 49
50// static struct MeshPeer *peer_head;
51//
52// static struct MeshPeer *peer_tail;
53
54/** 50/**
55 * How long until we give up on connecting the peers? 51 * How long until we give up on connecting the peers?
56 */ 52 */
57#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1500) 53#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1500)
58 54
55/**
56 * Time to wait for stuff that should be rather fast
57 */
58#define SHORT_TIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
59
60/**
61 * DIFFERENT TESTS TO RUN
62 */
63#define SETUP 0
64#define UNICAST 1
65#define MULTICAST 2
66
67/**
68 * Which test are we running?
69 */
70static int test;
71
72/**
73 * How many events have happened
74 */
59static int ok; 75static int ok;
60 76
61/** 77/**
@@ -99,11 +115,21 @@ static struct GNUNET_DISK_FileHandle *output_file;
99static struct GNUNET_DISK_FileHandle *data_file; 115static struct GNUNET_DISK_FileHandle *data_file;
100 116
101/** 117/**
118 * How many data points to capture before triggering next round?
119 */
120static struct GNUNET_TIME_Relative wait_time;
121
122/**
102 * Task called to disconnect peers. 123 * Task called to disconnect peers.
103 */ 124 */
104static GNUNET_SCHEDULER_TaskIdentifier disconnect_task; 125static GNUNET_SCHEDULER_TaskIdentifier disconnect_task;
105 126
106/** 127/**
128 * Task To perform tests
129 */
130static GNUNET_SCHEDULER_TaskIdentifier test_task;
131
132/**
107 * Task called to shutdown test. 133 * Task called to shutdown test.
108 */ 134 */
109static GNUNET_SCHEDULER_TaskIdentifier shutdown_handle; 135static GNUNET_SCHEDULER_TaskIdentifier shutdown_handle;
@@ -112,7 +138,21 @@ static char *topology_file;
112 138
113static char *data_filename; 139static char *data_filename;
114 140
115static struct GNUNET_TIME_Relative time_out; 141static struct GNUNET_TESTING_Daemon *d1;
142
143static GNUNET_PEER_Id pid1;
144
145static struct GNUNET_TESTING_Daemon *d2;
146
147static struct GNUNET_MESH_Handle *h1;
148
149static struct GNUNET_MESH_Handle *h2;
150
151static struct GNUNET_MESH_Tunnel *t;
152
153static struct GNUNET_MESH_Tunnel *incoming_t;
154
155static uint16_t *mesh_peers;
116 156
117/** 157/**
118 * Check whether peers successfully shut down. 158 * Check whether peers successfully shut down.
@@ -123,17 +163,15 @@ shutdown_callback (void *cls, const char *emsg)
123 if (emsg != NULL) 163 if (emsg != NULL)
124 { 164 {
125#if VERBOSE 165#if VERBOSE
126 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown of peers failed!\n"); 166 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Shutdown of peers failed!\n");
127#endif 167#endif
128 if (ok == 0) 168 ok--;
129 ok = 666;
130 } 169 }
131 else 170 else
132 { 171 {
133#if VERBOSE 172#if VERBOSE
134 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All peers successfully shut down!\n"); 173 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: All peers successfully shut down!\n");
135#endif 174#endif
136 ok = 0;
137 } 175 }
138} 176}
139 177
@@ -142,7 +180,7 @@ static void
142shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 180shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
143{ 181{
144#if VERBOSE 182#if VERBOSE
145 fprintf (stderr, "Ending test.\n"); 183 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Ending test.\n");
146#endif 184#endif
147 185
148 if (disconnect_task != GNUNET_SCHEDULER_NO_TASK) 186 if (disconnect_task != GNUNET_SCHEDULER_NO_TASK)
@@ -150,6 +188,7 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
150 GNUNET_SCHEDULER_cancel (disconnect_task); 188 GNUNET_SCHEDULER_cancel (disconnect_task);
151 disconnect_task = GNUNET_SCHEDULER_NO_TASK; 189 disconnect_task = GNUNET_SCHEDULER_NO_TASK;
152 } 190 }
191
153 if (data_file != NULL) 192 if (data_file != NULL)
154 GNUNET_DISK_file_close (data_file); 193 GNUNET_DISK_file_close (data_file);
155 GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); 194 GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL);
@@ -157,26 +196,132 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
157} 196}
158 197
159 198
199static void
200disconnect_mesh_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
201{
202 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
203 "test: disconnecting mesh service of peers\n");
204 disconnect_task = GNUNET_SCHEDULER_NO_TASK;
205 GNUNET_MESH_disconnect(h1);
206 GNUNET_MESH_disconnect(h2);
207 GNUNET_SCHEDULER_cancel (shutdown_handle);
208 shutdown_handle = GNUNET_SCHEDULER_add_now(&shutdown_task, NULL);
209}
210
211
212/**
213 * Transmit ready callback
214 */
215size_t
216tmt_rdy (void *cls, size_t size, void *buf)
217{
218 struct GNUNET_MessageHeader *msg = buf;
219
220 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: tmt_rdy called\n");
221 if (size < sizeof(struct GNUNET_MessageHeader) || NULL == buf)
222 return 0;
223 msg->size = htons (sizeof(struct GNUNET_MessageHeader));
224 msg->type = htons ((long) cls);
225 return sizeof(struct GNUNET_MessageHeader);
226}
227
228
229/**
230 * Function is called whenever a message is received.
231 *
232 * @param cls closure (set from GNUNET_MESH_connect)
233 * @param tunnel connection to the other end
234 * @param tunnel_ctx place to store local state associated with the tunnel
235 * @param sender who sent the message
236 * @param message the actual message
237 * @param atsi performance data for the connection
238 * @return GNUNET_OK to keep the connection open,
239 * GNUNET_SYSERR to close it (signal serious error)
240 */
241int
242data_callback (void *cls,
243 struct GNUNET_MESH_Tunnel * tunnel,
244 void **tunnel_ctx,
245 const struct GNUNET_PeerIdentity *sender,
246 const struct GNUNET_MessageHeader *message,
247 const struct GNUNET_ATS_Information *atsi)
248{
249 long client = (long) cls;
250
251 switch (client)
252 {
253 case 1L:
254 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
255 "test: Origin client got a response!\n");
256 ok++;
257 GNUNET_MESH_tunnel_destroy (tunnel);
258 GNUNET_SCHEDULER_cancel (disconnect_task);
259 disconnect_task = GNUNET_SCHEDULER_add_delayed(SHORT_TIME,
260 &disconnect_mesh_peers,
261 NULL);
262 break;
263 case 2L:
264 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
265 "test: Destination client got a message \n");
266 ok++;
267 GNUNET_MESH_notify_transmit_ready(incoming_t,
268 GNUNET_NO,
269 0,
270 GNUNET_TIME_UNIT_FOREVER_REL,
271 sender,
272 sizeof(struct GNUNET_MessageHeader),
273 &tmt_rdy,
274 (void *) 1L);
275 GNUNET_SCHEDULER_cancel (disconnect_task);
276 disconnect_task = GNUNET_SCHEDULER_add_delayed(SHORT_TIME,
277 &disconnect_mesh_peers,
278 NULL);
279 break;
280 default:
281 break;
282 }
283 return GNUNET_OK;
284}
285
286
160/** 287/**
161 * Handlers, for diverse services 288 * Handlers, for diverse services
162 */ 289 */
163static struct GNUNET_MESH_MessageHandler handlers[] = { 290static struct GNUNET_MESH_MessageHandler handlers[] = {
164// {&callback, 1, 0}, 291 {&data_callback, 1, sizeof(struct GNUNET_MessageHeader)},
165 {NULL, 0, 0} 292 {NULL, 0, 0}
166}; 293};
167 294
168 295
169static void 296/**
170disconnect_mesh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 297 * Method called whenever another peer has added us to a tunnel
298 * the other peer initiated.
299 *
300 * @param cls closure
301 * @param tunnel new handle to the tunnel
302 * @param initiator peer that started the tunnel
303 * @param atsi performance information for the tunnel
304 * @return initial tunnel context for the tunnel
305 * (can be NULL -- that's not an error)
306 */
307static void *
308incoming_tunnel (void *cls,
309 struct GNUNET_MESH_Tunnel * tunnel,
310 const struct GNUNET_PeerIdentity * initiator,
311 const struct GNUNET_ATS_Information * atsi)
171{ 312{
172 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 313 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
173 "test: disconnecting mesh service of peers\n"); 314 "test: Incoming tunnel from %s\n",
174 disconnect_task = GNUNET_SCHEDULER_NO_TASK; 315 GNUNET_i2s(initiator));
175 GNUNET_SCHEDULER_cancel (shutdown_handle); 316 ok++;
176 shutdown_handle = GNUNET_SCHEDULER_add_now(&shutdown_task, NULL); 317 incoming_t = tunnel;
318 GNUNET_SCHEDULER_cancel (disconnect_task);
319 disconnect_task = GNUNET_SCHEDULER_add_delayed(SHORT_TIME,
320 &disconnect_mesh_peers,
321 NULL);
322 return NULL;
177} 323}
178 324
179
180/** 325/**
181 * Function called whenever an inbound tunnel is destroyed. Should clean up 326 * Function called whenever an inbound tunnel is destroyed. Should clean up
182 * any associated state. 327 * any associated state.
@@ -190,12 +335,21 @@ static void
190tunnel_cleaner (void *cls, const struct GNUNET_MESH_Tunnel *tunnel, 335tunnel_cleaner (void *cls, const struct GNUNET_MESH_Tunnel *tunnel,
191 void *tunnel_ctx) 336 void *tunnel_ctx)
192{ 337{
193#if VERBOSE 338 long i = (long) cls;
194 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tunnel disconnected\n"); 339
195#endif 340 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
341 "test: Incoming tunnel disconnected at peer %d\n",
342 i);
343 if (2L == i)
344 ok++;
345
346 GNUNET_SCHEDULER_cancel (disconnect_task);
347 disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_mesh_peers, NULL);
348
196 return; 349 return;
197} 350}
198 351
352
199/** 353/**
200 * Method called whenever a tunnel falls apart. 354 * Method called whenever a tunnel falls apart.
201 * 355 *
@@ -205,13 +359,15 @@ tunnel_cleaner (void *cls, const struct GNUNET_MESH_Tunnel *tunnel,
205static void 359static void
206dh (void *cls, const struct GNUNET_PeerIdentity *peer) 360dh (void *cls, const struct GNUNET_PeerIdentity *peer)
207{ 361{
208 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer disconnected\n"); 362 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
363 "test: peer %s disconnected\n",
364 GNUNET_i2s(peer));
209 return; 365 return;
210} 366}
211 367
212 368
213/** 369/**
214 * Method called whenever a tunnel is established. 370 * Method called whenever a peer connects to a tunnel.
215 * 371 *
216 * @param cls closure 372 * @param cls closure
217 * @param peer peer identity the tunnel was created to, NULL on timeout 373 * @param peer peer identity the tunnel was created to, NULL on timeout
@@ -221,44 +377,180 @@ static void
221ch (void *cls, const struct GNUNET_PeerIdentity *peer, 377ch (void *cls, const struct GNUNET_PeerIdentity *peer,
222 const struct GNUNET_ATS_Information *atsi) 378 const struct GNUNET_ATS_Information *atsi)
223{ 379{
224 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer connected\n"); 380 struct GNUNET_PeerIdentity *dest;
381
382 switch (test)
383 {
384 case UNICAST:
385 dest = &d2->id;
386 break;
387 case MULTICAST:
388 dest = NULL;
389 break;
390 default:
391 return;
392 }
393
394 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
395 "test: peer %s connected\n",
396 GNUNET_i2s(peer));
397 if (0 == memcmp(&d2->id, peer, sizeof(d2->id)) && (long) cls == 1L)
398 ok++;
399 if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
400 {
401 GNUNET_SCHEDULER_cancel (disconnect_task);
402 disconnect_task = GNUNET_SCHEDULER_add_delayed(SHORT_TIME,
403 &disconnect_mesh_peers,
404 NULL);
405 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Sending data...\n");
406 GNUNET_MESH_notify_transmit_ready(t,
407 GNUNET_NO,
408 0,
409 GNUNET_TIME_UNIT_FOREVER_REL,
410 dest,
411 sizeof(struct GNUNET_MessageHeader),
412 &tmt_rdy,
413 (void *) 1L);
414 }
415 else
416 {
417 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Disconnect already run?\n");
418 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Aborting...\n");
419 }
225 return; 420 return;
226} 421}
227 422
228 423
424static void
425do_test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
426{
427 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: test_task\n");
428 GNUNET_MESH_peer_request_connect_add(t, &d2->id);
429 GNUNET_SCHEDULER_cancel (disconnect_task);
430 disconnect_task = GNUNET_SCHEDULER_add_delayed(
431 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30),
432 &disconnect_mesh_peers, NULL);
433}
434
435
436/**
437 * Prototype of a callback function indicating that two peers
438 * are currently connected.
439 *
440 * @param cls closure
441 * @param first peer id for first daemon
442 * @param second peer id for the second daemon
443 * @param distance distance between the connected peers
444 * @param emsg error message (NULL on success)
445 */
446void
447topo_cb (void *cls,
448 const struct GNUNET_PeerIdentity* first,
449 const struct GNUNET_PeerIdentity* second,
450 const char *emsg)
451{
452 GNUNET_PEER_Id p1;
453 GNUNET_PEER_Id p2;
454 struct GNUNET_PeerIdentity id;
455
456 GNUNET_PEER_resolve(1, &id);
457 p1 = GNUNET_PEER_search(first);
458 if (p1 == pid1)
459 {
460 p2 = GNUNET_PEER_search(second);
461 GNUNET_assert(p2 < num_peers);
462 GNUNET_assert(p2 > 0);
463 mesh_peers[p2]++;
464 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
465 "test: %s IS a neighbor\n",
466 GNUNET_i2s(second));
467 return;
468 }
469 p1 = GNUNET_PEER_search(second);
470 if (p1 == pid1)
471 {
472 p2 = GNUNET_PEER_search(first);
473 GNUNET_assert(p2 < num_peers);
474 GNUNET_assert(p2 > 0);
475 mesh_peers[p2]++;
476 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
477 "test: %s IS a neighbor\n",
478 GNUNET_i2s(first));
479 return;
480 }
481}
482
229/** 483/**
230 * connect_mesh_service: connect to the mesh service of one of the peers 484 * connect_mesh_service: connect to the mesh service of one of the peers
231 * 485 *
232 */ 486 */
233static void 487static void
234connect_mesh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 488connect_mesh_service (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
235{ 489{
236 struct GNUNET_TESTING_Daemon *d;
237 struct GNUNET_MESH_Handle *h;
238 struct GNUNET_MESH_Tunnel *t;
239 GNUNET_MESH_ApplicationType app; 490 GNUNET_MESH_ApplicationType app;
491 unsigned int i;
492 struct GNUNET_PeerIdentity id;
240 493
241 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "connect_mesh_service\n"); 494 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: connect_mesh_service\n");
242 495
243 d = GNUNET_TESTING_daemon_get (pg, 1); 496 for (i = 1; i <= num_peers; i++)
497 {
498 GNUNET_PEER_resolve(i, &id);
499 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
500 "test: peer %s has %u conns to d1\n",
501 GNUNET_i2s (&id),
502 mesh_peers[i]);
503 if (mesh_peers[i] == 0)
504 break;
505 }
506 GNUNET_assert (i < num_peers);
507 d2 = GNUNET_TESTING_daemon_get_by_id (pg, &id);
508 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
509 "test: Peer searched: %s\n",
510 GNUNET_i2s (&d2->id));
244 app = (GNUNET_MESH_ApplicationType) 0; 511 app = (GNUNET_MESH_ApplicationType) 0;
245 512
246#if VERBOSE 513#if VERBOSE
247 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 514 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
248 "connecting to mesh service of peer %s\n", GNUNET_i2s (&d->id)); 515 "test: connecting to mesh service of peer %s (%u)\n",
516 GNUNET_i2s (&d1->id),
517 mesh_peers[0]);
518 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
519 "test: connecting to mesh service of peer %s (%u)\n",
520 GNUNET_i2s (&d2->id),
521 i);
249#endif 522#endif
250 h = GNUNET_MESH_connect (d->cfg, 10, NULL, NULL, &tunnel_cleaner, handlers, 523 h1 = GNUNET_MESH_connect (d1->cfg,
251 &app); 524 10,
525 (void *) 1L,
526 NULL,
527 &tunnel_cleaner,
528 handlers,
529 &app);
530 h2 = GNUNET_MESH_connect (d2->cfg,
531 10,
532 (void *) 2L,
533 &incoming_tunnel,
534 &tunnel_cleaner,
535 handlers,
536 &app);
252#if VERBOSE 537#if VERBOSE
253 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "connected to mesh service of peer %s\n", 538 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
254 GNUNET_i2s (&d->id)); 539 "test: connected to mesh service of peer %s\n",
540 GNUNET_i2s (&d1->id));
541 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
542 "test: connected to mesh service of peer %s\n",
543 GNUNET_i2s (&d2->id));
255#endif 544#endif
256 t = GNUNET_MESH_tunnel_create (h, NULL, &ch, &dh, NULL); 545 t = GNUNET_MESH_tunnel_create (h1, NULL, &ch, &dh, (void *) 1L);
257 GNUNET_MESH_tunnel_destroy (t); 546 test_task =
258 GNUNET_MESH_disconnect (h); 547 GNUNET_SCHEDULER_add_delayed(
548 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 6),
549 &do_test, NULL);
259} 550}
260 551
261 552
553
262/** 554/**
263 * peergroup_ready: start test when all peers are connected 555 * peergroup_ready: start test when all peers are connected
264 * @param cls closure 556 * @param cls closure
@@ -269,22 +561,28 @@ peergroup_ready (void *cls, const char *emsg)
269{ 561{
270 char *buf; 562 char *buf;
271 int buf_len; 563 int buf_len;
564 unsigned int i;
272 565
273 if (emsg != NULL) 566 if (emsg != NULL)
274 { 567 {
275 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 568 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
276 "Peergroup callback called with error, aborting test!\n"); 569 "test: Peergroup callback called with error, aborting test!\n");
277 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Error from testing: `%s'\n"); 570 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
278 ok = 1; 571 "test: Error from testing: `%s'\n", emsg);
572 ok--;
279 GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); 573 GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL);
280 return; 574 return;
281 } 575 }
282#if VERBOSE 576#if VERBOSE
283 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer Group started successfully!\n"); 577 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
578 "************************************************************\n");
579 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
580 "test: Peer Group started successfully!\n");
581 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
582 "test: Have %u connections\n",
583 total_connections);
284#endif 584#endif
285 585
286 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Have %u connections\n",
287 total_connections);
288 if (data_file != NULL) 586 if (data_file != NULL)
289 { 587 {
290 buf = NULL; 588 buf = NULL;
@@ -294,10 +592,29 @@ peergroup_ready (void *cls, const char *emsg)
294 GNUNET_free (buf); 592 GNUNET_free (buf);
295 } 593 }
296 peers_running = GNUNET_TESTING_daemons_running (pg); 594 peers_running = GNUNET_TESTING_daemons_running (pg);
297 595 for (i = 0; i < num_peers; i++)
298 GNUNET_SCHEDULER_add_now (&connect_mesh, NULL); 596 {
597 d1 = GNUNET_TESTING_daemon_get (pg, i);
598 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
599 "test: %u: %s\n",
600 GNUNET_PEER_intern(&d1->id),
601 GNUNET_i2s (&d1->id));
602 }
603 d1 = GNUNET_TESTING_daemon_get (pg, 0);
604 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
605 "test: Peer looking: %s\n",
606 GNUNET_i2s (&d1->id));
607 pid1 = GNUNET_PEER_intern(&d1->id);
608 mesh_peers[pid1] = 100;
609 GNUNET_TESTING_get_topology(pg, &topo_cb, NULL);
610
611 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(
612 GNUNET_TIME_UNIT_SECONDS,
613 4),
614 &connect_mesh_service,
615 NULL);
299 disconnect_task = 616 disconnect_task =
300 GNUNET_SCHEDULER_add_delayed (time_out, &disconnect_mesh, NULL); 617 GNUNET_SCHEDULER_add_delayed (wait_time, &disconnect_mesh_peers, NULL);
301 618
302} 619}
303 620
@@ -325,7 +642,16 @@ connect_cb (void *cls, const struct GNUNET_PeerIdentity *first,
325 struct GNUNET_TESTING_Daemon *second_daemon, const char *emsg) 642 struct GNUNET_TESTING_Daemon *second_daemon, const char *emsg)
326{ 643{
327 if (emsg == NULL) 644 if (emsg == NULL)
645 {
328 total_connections++; 646 total_connections++;
647 }
648 else
649 {
650 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
651 "test: Problem with new connection (%s)\n",
652 emsg);
653 }
654
329} 655}
330 656
331 657
@@ -341,9 +667,10 @@ run (void *cls, char *const *args, const char *cfgfile,
341 const struct GNUNET_CONFIGURATION_Handle *cfg) 667 const struct GNUNET_CONFIGURATION_Handle *cfg)
342{ 668{
343 char *temp_str; 669 char *temp_str;
670 unsigned long long temp_wait;
344 struct GNUNET_TESTING_Host *hosts; 671 struct GNUNET_TESTING_Host *hosts;
345 672
346 ok = 1; 673 ok = 0;
347 testing_cfg = GNUNET_CONFIGURATION_dup (cfg); 674 testing_cfg = GNUNET_CONFIGURATION_dup (cfg);
348 675
349 GNUNET_log_setup ("test_mesh_small", 676 GNUNET_log_setup ("test_mesh_small",
@@ -355,28 +682,29 @@ run (void *cls, char *const *args, const char *cfgfile,
355 NULL); 682 NULL);
356 683
357#if VERBOSE 684#if VERBOSE
358 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting daemons.\n"); 685 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Starting daemons.\n");
359 GNUNET_CONFIGURATION_set_value_string (testing_cfg, "testing", 686 GNUNET_CONFIGURATION_set_value_string (testing_cfg, "testing",
360 "use_progressbars", "YES"); 687 "use_progressbars", "YES");
361#endif 688#endif
362 689
363 time_out = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30);
364
365 if (GNUNET_OK != 690 if (GNUNET_OK !=
366 GNUNET_CONFIGURATION_get_value_number (testing_cfg, "testing", 691 GNUNET_CONFIGURATION_get_value_number (testing_cfg, "testing",
367 "num_peers", &num_peers)) 692 "num_peers", &num_peers))
368 { 693 {
369 GNUNET_assert (GNUNET_OK == 694 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
370 GNUNET_CONFIGURATION_load (testing_cfg, 695 "Option TESTING:NUM_PEERS is required!\n");
371 "test_mesh_small.conf")); 696 return;
372 if (GNUNET_OK != 697 }
373 GNUNET_CONFIGURATION_get_value_number (testing_cfg, "testing", 698
374 "num_peers", &num_peers)) 699 mesh_peers = GNUNET_malloc (sizeof(GNUNET_PEER_Id) * (num_peers + 1));
375 { 700
376 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 701 if (GNUNET_OK !=
377 "Option TESTING:NUM_PEERS is required!\n"); 702 GNUNET_CONFIGURATION_get_value_number (testing_cfg, "test_mesh_small",
378 return; 703 "wait_time", &temp_wait))
379 } 704 {
705 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
706 "Option test_mesh_small:wait_time is required!\n");
707 return;
380 } 708 }
381 709
382 if (GNUNET_OK != 710 if (GNUNET_OK !=
@@ -412,6 +740,9 @@ run (void *cls, char *const *args, const char *cfgfile,
412 GNUNET_free (data_filename); 740 GNUNET_free (data_filename);
413 } 741 }
414 742
743 wait_time =
744 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, temp_wait);
745
415 if (GNUNET_YES == 746 if (GNUNET_YES ==
416 GNUNET_CONFIGURATION_get_value_string (cfg, "test_mesh_small", 747 GNUNET_CONFIGURATION_get_value_string (cfg, "test_mesh_small",
417 "output_file", &temp_str)) 748 "output_file", &temp_str))
@@ -458,13 +789,56 @@ static struct GNUNET_GETOPT_CommandLineOption options[] = {
458int 789int
459main (int argc, char *argv[]) 790main (int argc, char *argv[])
460{ 791{
461 GNUNET_PROGRAM_run (argc, argv, "test_mesh_small", 792 char *const argv2[] = {
462 gettext_noop ("Test mesh in a small network."), options, 793 argv[0],
463 &run, NULL); 794 "-c",
795 "test_mesh_small.conf",
796#if VERBOSE
797 "-L",
798 "DEBUG",
799#endif
800 NULL
801 };
802 int ok_goal;
803
804 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Start\n");
805 if (strstr (argv[0], "test_mesh_small_unicast") != NULL)
806 {
807 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: UNICAST\n");
808 test = UNICAST;
809 ok_goal = 5;
810 }
811 else if (strstr (argv[0], "test_mesh_small_multicast") != NULL)
812 {
813 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: MULTICAST\n");
814 test = MULTICAST;
815 ok_goal = 5;
816 }
817 else
818 {
819 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: UNKNOWN\n");
820 test = SETUP;
821 ok_goal = 0;
822 }
823
824 GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
825 "test_mesh_small",
826 gettext_noop ("Test mesh in a small network."),
827 options, &run, NULL);
464#if REMOVE_DIR 828#if REMOVE_DIR
465 GNUNET_DISK_directory_remove ("/tmp/test_mesh_small"); 829 GNUNET_DISK_directory_remove ("/tmp/test_mesh_small");
466#endif 830#endif
467 return ok; 831 if (ok_goal != ok)
832 {
833 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
834 "test: %s FAILED! (%d/%d)\n",
835 argv[0], ok, ok_goal);
836 return 1;
837 }
838 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
839 "test: %s success\n",
840 argv[0]);
841 return 0;
468} 842}
469 843
470/* end of test_mesh_small.c */ 844/* end of test_mesh_small.c */
diff --git a/src/mesh/test_mesh_small_multicast.c b/src/mesh/test_mesh_small_multicast.c
deleted file mode 100644
index f9b69506e..000000000
--- a/src/mesh/test_mesh_small_multicast.c
+++ /dev/null
@@ -1,776 +0,0 @@
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 * @file mesh/test_mesh_small_multicast.c
22 *
23 * @brief Test for the mesh service: retransmission of multicast traffic.
24 */
25#include "platform.h"
26#include "gnunet_testing_lib.h"
27#include "gnunet_mesh_service_new.h"
28
29#define VERBOSE GNUNET_YES
30#define REMOVE_DIR GNUNET_YES
31
32struct MeshPeer
33{
34 struct MeshPeer *prev;
35
36 struct MeshPeer *next;
37
38 struct GNUNET_TESTING_Daemon *daemon;
39
40 struct GNUNET_MESH_Handle *mesh_handle;
41};
42
43
44struct StatsContext
45{
46 unsigned long long total_mesh_bytes;
47};
48
49
50/**
51 * How long until we give up on connecting the peers?
52 */
53#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1500)
54
55/**
56 * Time to wait for stuff that should be rather fast
57 */
58#define SHORT_TIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
59
60#define OK_GOAL 4
61
62static int ok;
63
64/**
65 * Be verbose
66 */
67static int verbose;
68
69/**
70 * Total number of peers in the test.
71 */
72static unsigned long long num_peers;
73
74/**
75 * Global configuration file
76 */
77static struct GNUNET_CONFIGURATION_Handle *testing_cfg;
78
79/**
80 * Total number of currently running peers.
81 */
82static unsigned long long peers_running;
83
84/**
85 * Total number of connections in the whole network.
86 */
87static unsigned int total_connections;
88
89/**
90 * The currently running peer group.
91 */
92static struct GNUNET_TESTING_PeerGroup *pg;
93
94/**
95 * File to report results to.
96 */
97static struct GNUNET_DISK_FileHandle *output_file;
98
99/**
100 * File to log connection info, statistics to.
101 */
102static struct GNUNET_DISK_FileHandle *data_file;
103
104/**
105 * How many data points to capture before triggering next round?
106 */
107static struct GNUNET_TIME_Relative wait_time;
108
109/**
110 * Task called to disconnect peers.
111 */
112static GNUNET_SCHEDULER_TaskIdentifier disconnect_task;
113
114/**
115 * Task To perform tests
116 */
117static GNUNET_SCHEDULER_TaskIdentifier test_task;
118
119/**
120 * Task called to shutdown test.
121 */
122static GNUNET_SCHEDULER_TaskIdentifier shutdown_handle;
123
124static char *topology_file;
125
126static char *data_filename;
127
128static struct GNUNET_TESTING_Daemon *d1;
129
130static GNUNET_PEER_Id pid1;
131
132static struct GNUNET_TESTING_Daemon *d2;
133
134static struct GNUNET_MESH_Handle *h1;
135
136static struct GNUNET_MESH_Handle *h2;
137
138static struct GNUNET_MESH_Tunnel *t;
139
140static struct GNUNET_MESH_Tunnel *incoming_t;
141
142static uint16_t *mesh_peers;
143
144/**
145 * Check whether peers successfully shut down.
146 */
147static void
148shutdown_callback (void *cls, const char *emsg)
149{
150 if (emsg != NULL)
151 {
152#if VERBOSE
153 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Shutdown of peers failed!\n");
154#endif
155 ok--;
156 }
157 else
158 {
159#if VERBOSE
160 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: All peers successfully shut down!\n");
161#endif
162 }
163}
164
165
166static void
167shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
168{
169#if VERBOSE
170 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Ending test.\n");
171#endif
172
173 if (disconnect_task != GNUNET_SCHEDULER_NO_TASK)
174 {
175 GNUNET_SCHEDULER_cancel (disconnect_task);
176 disconnect_task = GNUNET_SCHEDULER_NO_TASK;
177 }
178
179 if (data_file != NULL)
180 GNUNET_DISK_file_close (data_file);
181 GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL);
182 GNUNET_CONFIGURATION_destroy (testing_cfg);
183}
184
185
186static void
187disconnect_mesh_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
188{
189 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
190 "test: disconnecting mesh service of peers\n");
191 disconnect_task = GNUNET_SCHEDULER_NO_TASK;
192 GNUNET_MESH_disconnect(h1);
193 GNUNET_MESH_disconnect(h2);
194 GNUNET_SCHEDULER_cancel (shutdown_handle);
195 shutdown_handle = GNUNET_SCHEDULER_add_now(&shutdown_task, NULL);
196}
197
198
199/**
200 * Transmit ready callback
201 */
202size_t
203tmt_rdy (void *cls, size_t size, void *buf)
204{
205 struct GNUNET_MessageHeader *msg = buf;
206
207 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: tmt_rdy called\n");
208 if (size < sizeof(struct GNUNET_MessageHeader) || NULL == buf)
209 return 0;
210 msg->size = htons (sizeof(struct GNUNET_MessageHeader));
211 msg->type = htons ((long) cls);
212 return sizeof(struct GNUNET_MessageHeader);
213}
214
215
216/**
217 * Function is called whenever a message is received.
218 *
219 * @param cls closure (set from GNUNET_MESH_connect)
220 * @param tunnel connection to the other end
221 * @param tunnel_ctx place to store local state associated with the tunnel
222 * @param sender who sent the message
223 * @param message the actual message
224 * @param atsi performance data for the connection
225 * @return GNUNET_OK to keep the connection open,
226 * GNUNET_SYSERR to close it (signal serious error)
227 */
228int
229data_callback (void *cls,
230 struct GNUNET_MESH_Tunnel * tunnel,
231 void **tunnel_ctx,
232 const struct GNUNET_PeerIdentity *sender,
233 const struct GNUNET_MessageHeader *message,
234 const struct GNUNET_ATS_Information *atsi)
235{
236 long client = (long) cls;
237
238 switch (client)
239 {
240 case 1L:
241 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
242 "test: Origin client got a response!\n");
243 ok++;
244 GNUNET_SCHEDULER_cancel (disconnect_task);
245 disconnect_task = GNUNET_SCHEDULER_add_now(&disconnect_mesh_peers,
246 NULL);
247 break;
248 case 2L:
249 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
250 "test: Destination client got a message \n");
251 ok++;
252 GNUNET_MESH_notify_transmit_ready(incoming_t,
253 GNUNET_NO,
254 0,
255 GNUNET_TIME_UNIT_FOREVER_REL,
256 sender,
257 sizeof(struct GNUNET_MessageHeader),
258 &tmt_rdy,
259 (void *) 1L);
260 GNUNET_SCHEDULER_cancel (disconnect_task);
261 disconnect_task = GNUNET_SCHEDULER_add_delayed(SHORT_TIME,
262 &disconnect_mesh_peers,
263 NULL);
264 break;
265 default:
266 break;
267 }
268 return GNUNET_OK;
269}
270
271
272/**
273 * Handlers, for diverse services
274 */
275static struct GNUNET_MESH_MessageHandler handlers[] = {
276 {&data_callback, 1, sizeof(struct GNUNET_MessageHeader)},
277 {NULL, 0, 0}
278};
279
280
281/**
282 * Method called whenever another peer has added us to a tunnel
283 * the other peer initiated.
284 *
285 * @param cls closure
286 * @param tunnel new handle to the tunnel
287 * @param initiator peer that started the tunnel
288 * @param atsi performance information for the tunnel
289 * @return initial tunnel context for the tunnel
290 * (can be NULL -- that's not an error)
291 */
292static void *
293incoming_tunnel (void *cls,
294 struct GNUNET_MESH_Tunnel * tunnel,
295 const struct GNUNET_PeerIdentity * initiator,
296 const struct GNUNET_ATS_Information * atsi)
297{
298 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
299 "test: Incoming tunnel from %s\n",
300 GNUNET_i2s(initiator));
301 ok++;
302 incoming_t = tunnel;
303 GNUNET_SCHEDULER_cancel (disconnect_task);
304 disconnect_task = GNUNET_SCHEDULER_add_delayed(SHORT_TIME,
305 &disconnect_mesh_peers,
306 NULL);
307 return NULL;
308}
309
310/**
311 * Function called whenever an inbound tunnel is destroyed. Should clean up
312 * any associated state.
313 *
314 * @param cls closure (set from GNUNET_MESH_connect)
315 * @param tunnel connection to the other end (henceforth invalid)
316 * @param tunnel_ctx place where local state associated
317 * with the tunnel is stored
318 */
319static void
320tunnel_cleaner (void *cls, const struct GNUNET_MESH_Tunnel *tunnel,
321 void *tunnel_ctx)
322{
323#if VERBOSE
324 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: tunnel disconnected\n");
325#endif
326
327 return;
328}
329
330
331/**
332 * Method called whenever a tunnel falls apart.
333 *
334 * @param cls closure
335 * @param peer peer identity the tunnel stopped working with
336 */
337static void
338dh (void *cls, const struct GNUNET_PeerIdentity *peer)
339{
340 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
341 "test: peer %s disconnected\n",
342 GNUNET_i2s(peer));
343 return;
344}
345
346
347/**
348 * Method called whenever a tunnel is established.
349 *
350 * @param cls closure
351 * @param peer peer identity the tunnel was created to, NULL on timeout
352 * @param atsi performance data for the connection
353 */
354static void
355ch (void *cls, const struct GNUNET_PeerIdentity *peer,
356 const struct GNUNET_ATS_Information *atsi)
357{
358 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
359 "test: peer %s connected\n",
360 GNUNET_i2s(peer));
361 if (0 == memcmp(&d2->id, peer, sizeof(d2->id)) && (long) cls == 1L)
362 ok++;
363 if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
364 {
365 GNUNET_SCHEDULER_cancel (disconnect_task);
366 disconnect_task = GNUNET_SCHEDULER_add_delayed(SHORT_TIME,
367 &disconnect_mesh_peers,
368 NULL);
369 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Sending data multicast...\n");
370 GNUNET_MESH_notify_transmit_ready(t,
371 GNUNET_NO,
372 0,
373 GNUNET_TIME_UNIT_FOREVER_REL,
374 NULL,
375 sizeof(struct GNUNET_MessageHeader),
376 &tmt_rdy,
377 (void *) 1L);
378 }
379 return;
380}
381
382
383static void
384do_test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
385{
386 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: test_task\n");
387 GNUNET_MESH_peer_request_connect_add(t, &d2->id);
388 GNUNET_SCHEDULER_cancel (disconnect_task);
389 disconnect_task = GNUNET_SCHEDULER_add_delayed(
390 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30),
391 &disconnect_mesh_peers, NULL);
392}
393
394
395/**
396 * Prototype of a callback function indicating that two peers
397 * are currently connected.
398 *
399 * @param cls closure
400 * @param first peer id for first daemon
401 * @param second peer id for the second daemon
402 * @param distance distance between the connected peers
403 * @param emsg error message (NULL on success)
404 */
405void
406topo_cb (void *cls,
407 const struct GNUNET_PeerIdentity* first,
408 const struct GNUNET_PeerIdentity* second,
409 const char *emsg)
410{
411 GNUNET_PEER_Id p1;
412 GNUNET_PEER_Id p2;
413 struct GNUNET_PeerIdentity id;
414
415 GNUNET_PEER_resolve(1, &id);
416 p1 = GNUNET_PEER_search(first);
417 if (p1 == pid1)
418 {
419 p2 = GNUNET_PEER_search(second);
420 GNUNET_assert(p2 < num_peers);
421 GNUNET_assert(p2 > 0);
422 mesh_peers[p2]++;
423 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
424 "test: %s IS a neighbor\n",
425 GNUNET_i2s(second));
426 return;
427 }
428 p1 = GNUNET_PEER_search(second);
429 if (p1 == pid1)
430 {
431 p2 = GNUNET_PEER_search(first);
432 GNUNET_assert(p2 < num_peers);
433 GNUNET_assert(p2 > 0);
434 mesh_peers[p2]++;
435 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
436 "test: %s IS a neighbor\n",
437 GNUNET_i2s(first));
438 return;
439 }
440}
441
442/**
443 * connect_mesh_service: connect to the mesh service of one of the peers
444 *
445 */
446static void
447connect_mesh_service (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
448{
449 GNUNET_MESH_ApplicationType app;
450 unsigned int i;
451 struct GNUNET_PeerIdentity id;
452
453 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: connect_mesh_service\n");
454
455 for (i = 1; i <= num_peers; i++)
456 {
457 GNUNET_PEER_resolve(i, &id);
458 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
459 "test: peer %s has %u conns to d1\n",
460 GNUNET_i2s (&id),
461 mesh_peers[i]);
462 if (mesh_peers[i] == 0)
463 break;
464 }
465 GNUNET_assert (i < num_peers);
466 d2 = GNUNET_TESTING_daemon_get_by_id (pg, &id);
467 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
468 "test: Peer searched: %s\n",
469 GNUNET_i2s (&d2->id));
470 app = (GNUNET_MESH_ApplicationType) 0;
471
472#if VERBOSE
473 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
474 "test: connecting to mesh service of peer %s (%u)\n",
475 GNUNET_i2s (&d1->id),
476 mesh_peers[0]);
477 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
478 "test: connecting to mesh service of peer %s (%u)\n",
479 GNUNET_i2s (&d2->id),
480 i);
481#endif
482 h1 = GNUNET_MESH_connect (d1->cfg,
483 10,
484 (void *) 1L,
485 NULL,
486 &tunnel_cleaner,
487 handlers,
488 &app);
489 h2 = GNUNET_MESH_connect (d2->cfg,
490 10,
491 (void *) 2L,
492 &incoming_tunnel,
493 &tunnel_cleaner,
494 handlers,
495 &app);
496#if VERBOSE
497 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
498 "test: connected to mesh service of peer %s\n",
499 GNUNET_i2s (&d1->id));
500 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
501 "test: connected to mesh service of peer %s\n",
502 GNUNET_i2s (&d2->id));
503#endif
504 t = GNUNET_MESH_tunnel_create (h1, NULL, &ch, &dh, (void *) 1L);
505 test_task =
506 GNUNET_SCHEDULER_add_delayed(
507 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 6),
508 &do_test, NULL);
509}
510
511
512
513/**
514 * peergroup_ready: start test when all peers are connected
515 * @param cls closure
516 * @param emsg error message
517 */
518static void
519peergroup_ready (void *cls, const char *emsg)
520{
521 char *buf;
522 int buf_len;
523 unsigned int i;
524
525 if (emsg != NULL)
526 {
527 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
528 "test: Peergroup callback called with error, aborting test!\n");
529 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
530 "test: Error from testing: `%s'\n", emsg);
531 ok--;
532 GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL);
533 return;
534 }
535#if VERBOSE
536 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
537 "************************************************************\n");
538 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
539 "test: Peer Group started successfully!\n");
540 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
541 "test: Have %u connections\n",
542 total_connections);
543#endif
544
545 if (data_file != NULL)
546 {
547 buf = NULL;
548 buf_len = GNUNET_asprintf (&buf, "CONNECTIONS_0: %u\n", total_connections);
549 if (buf_len > 0)
550 GNUNET_DISK_file_write (data_file, buf, buf_len);
551 GNUNET_free (buf);
552 }
553 peers_running = GNUNET_TESTING_daemons_running (pg);
554 for (i = 0; i < num_peers; i++)
555 {
556 d1 = GNUNET_TESTING_daemon_get (pg, i);
557 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
558 "test: %u: %s\n",
559 GNUNET_PEER_intern(&d1->id),
560 GNUNET_i2s (&d1->id));
561 }
562 d1 = GNUNET_TESTING_daemon_get (pg, 0);
563 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
564 "test: Peer looking: %s\n",
565 GNUNET_i2s (&d1->id));
566 pid1 = GNUNET_PEER_intern(&d1->id);
567 mesh_peers[pid1] = 100;
568 GNUNET_TESTING_get_topology(pg, &topo_cb, NULL);
569
570 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(
571 GNUNET_TIME_UNIT_SECONDS,
572 4),
573 &connect_mesh_service,
574 NULL);
575 disconnect_task =
576 GNUNET_SCHEDULER_add_delayed (wait_time, &disconnect_mesh_peers, NULL);
577
578}
579
580
581/**
582 * Function that will be called whenever two daemons are connected by
583 * the testing library.
584 *
585 * @param cls closure
586 * @param first peer id for first daemon
587 * @param second peer id for the second daemon
588 * @param distance distance between the connected peers
589 * @param first_cfg config for the first daemon
590 * @param second_cfg config for the second daemon
591 * @param first_daemon handle for the first daemon
592 * @param second_daemon handle for the second daemon
593 * @param emsg error message (NULL on success)
594 */
595static void
596connect_cb (void *cls, const struct GNUNET_PeerIdentity *first,
597 const struct GNUNET_PeerIdentity *second, uint32_t distance,
598 const struct GNUNET_CONFIGURATION_Handle *first_cfg,
599 const struct GNUNET_CONFIGURATION_Handle *second_cfg,
600 struct GNUNET_TESTING_Daemon *first_daemon,
601 struct GNUNET_TESTING_Daemon *second_daemon, const char *emsg)
602{
603 if (emsg == NULL)
604 {
605 total_connections++;
606 }
607 else
608 {
609 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
610 "test: Problem with new connection (%s)\n",
611 emsg);
612 }
613
614}
615
616
617/**
618 * run: load configuration options and schedule test to run (start peergroup)
619 * @param cls closure
620 * @param args argv
621 * @param cfgfile configuration file name (can be NULL)
622 * @param cfg configuration handle
623 */
624static void
625run (void *cls, char *const *args, const char *cfgfile,
626 const struct GNUNET_CONFIGURATION_Handle *cfg)
627{
628 char *temp_str;
629 unsigned long long temp_wait;
630 struct GNUNET_TESTING_Host *hosts;
631
632 ok = 0;
633 testing_cfg = GNUNET_CONFIGURATION_dup (cfg);
634
635 GNUNET_log_setup ("test_mesh_small_multicast",
636#if VERBOSE
637 "DEBUG",
638#else
639 "WARNING",
640#endif
641 NULL);
642
643#if VERBOSE
644 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Starting daemons.\n");
645 GNUNET_CONFIGURATION_set_value_string (testing_cfg, "testing",
646 "use_progressbars", "YES");
647#endif
648
649 if (GNUNET_OK !=
650 GNUNET_CONFIGURATION_get_value_number (testing_cfg, "testing",
651 "num_peers", &num_peers))
652 {
653 GNUNET_assert (GNUNET_OK ==
654 GNUNET_CONFIGURATION_load (testing_cfg,
655 "test_mesh_small.conf"));
656 if (GNUNET_OK !=
657 GNUNET_CONFIGURATION_get_value_number (testing_cfg, "testing",
658 "num_peers", &num_peers))
659 {
660 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
661 "Option TESTING:NUM_PEERS is required!\n");
662 return;
663 }
664 }
665
666 mesh_peers = GNUNET_malloc (sizeof(GNUNET_PEER_Id) * (num_peers + 1));
667
668 if (GNUNET_OK !=
669 GNUNET_CONFIGURATION_get_value_number (testing_cfg, "test_mesh_small",
670 "wait_time", &temp_wait))
671 {
672 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
673 "Option test_mesh_small:wait_time is required!\n");
674 return;
675 }
676
677 if (GNUNET_OK !=
678 GNUNET_CONFIGURATION_get_value_string (testing_cfg, "testing",
679 "topology_output_file",
680 &topology_file))
681 {
682 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
683 "Option test_mesh_small:topology_output_file is required!\n");
684 return;
685 }
686
687 if (GNUNET_OK !=
688 GNUNET_CONFIGURATION_get_value_string (testing_cfg, "test_mesh_small",
689 "data_output_file",
690 &data_filename))
691 {
692 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
693 "Option test_mesh_small:data_output_file is required!\n");
694 return;
695 }
696
697 data_file =
698 GNUNET_DISK_file_open (data_filename,
699 GNUNET_DISK_OPEN_READWRITE |
700 GNUNET_DISK_OPEN_CREATE,
701 GNUNET_DISK_PERM_USER_READ |
702 GNUNET_DISK_PERM_USER_WRITE);
703 if (data_file == NULL)
704 {
705 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to open %s for output!\n",
706 data_filename);
707 GNUNET_free (data_filename);
708 }
709
710 wait_time =
711 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, temp_wait);
712
713 if (GNUNET_YES ==
714 GNUNET_CONFIGURATION_get_value_string (cfg, "test_mesh_small",
715 "output_file", &temp_str))
716 {
717 output_file =
718 GNUNET_DISK_file_open (temp_str,
719 GNUNET_DISK_OPEN_READWRITE |
720 GNUNET_DISK_OPEN_CREATE,
721 GNUNET_DISK_PERM_USER_READ |
722 GNUNET_DISK_PERM_USER_WRITE);
723 if (output_file == NULL)
724 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to open %s for output!\n",
725 temp_str);
726 }
727 GNUNET_free_non_null (temp_str);
728
729 hosts = GNUNET_TESTING_hosts_load (testing_cfg);
730
731 pg = GNUNET_TESTING_peergroup_start (testing_cfg, num_peers, TIMEOUT,
732 &connect_cb, &peergroup_ready, NULL,
733 hosts);
734 GNUNET_assert (pg != NULL);
735 shutdown_handle =
736 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_get_forever (),
737 &shutdown_task, NULL);
738}
739
740
741
742/**
743 * test_mesh_small command line options
744 */
745static struct GNUNET_GETOPT_CommandLineOption options[] = {
746 {'V', "verbose", NULL,
747 gettext_noop ("be verbose (print progress information)"),
748 0, &GNUNET_GETOPT_set_one, &verbose},
749 GNUNET_GETOPT_OPTION_END
750};
751
752
753/**
754 * Main: start test
755 */
756int
757main (int argc, char *argv[])
758{
759 GNUNET_PROGRAM_run (argc, argv, "test_mesh_small_multicast",
760 gettext_noop ("Test mesh multicast in a small network."),
761 options, &run, NULL);
762#if REMOVE_DIR
763 GNUNET_DISK_directory_remove ("/tmp/test_mesh_small_multicast");
764#endif
765 if (OK_GOAL != ok)
766 {
767 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
768 "test: FAILED! (%d/%d)\n",
769 ok, OK_GOAL);
770 return 1;
771 }
772 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: success\n");
773 return 0;
774}
775
776/* end of test_mesh_small_multicast.c */
diff --git a/src/mesh/test_mesh_small_unicast.c b/src/mesh/test_mesh_small_unicast.c
deleted file mode 100644
index ad5a0fd22..000000000
--- a/src/mesh/test_mesh_small_unicast.c
+++ /dev/null
@@ -1,785 +0,0 @@
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 * @file mesh/test_mesh_small_unicast.c
22 *
23 * @brief Test for the mesh service: retransmission of unicast traffic.
24 */
25#include "platform.h"
26#include "gnunet_testing_lib.h"
27#include "gnunet_mesh_service_new.h"
28
29#define VERBOSE GNUNET_YES
30#define REMOVE_DIR GNUNET_YES
31
32struct MeshPeer
33{
34 struct MeshPeer *prev;
35
36 struct MeshPeer *next;
37
38 struct GNUNET_TESTING_Daemon *daemon;
39
40 struct GNUNET_MESH_Handle *mesh_handle;
41};
42
43
44struct StatsContext
45{
46 unsigned long long total_mesh_bytes;
47};
48
49
50/**
51 * How long until we give up on connecting the peers?
52 */
53#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1500)
54
55/**
56 * Time to wait for stuff that should be rather fast
57 */
58#define SHORT_TIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
59
60#define OK_GOAL 5
61
62static int ok;
63
64/**
65 * Be verbose
66 */
67static int verbose;
68
69/**
70 * Total number of peers in the test.
71 */
72static unsigned long long num_peers;
73
74/**
75 * Global configuration file
76 */
77static struct GNUNET_CONFIGURATION_Handle *testing_cfg;
78
79/**
80 * Total number of currently running peers.
81 */
82static unsigned long long peers_running;
83
84/**
85 * Total number of connections in the whole network.
86 */
87static unsigned int total_connections;
88
89/**
90 * The currently running peer group.
91 */
92static struct GNUNET_TESTING_PeerGroup *pg;
93
94/**
95 * File to report results to.
96 */
97static struct GNUNET_DISK_FileHandle *output_file;
98
99/**
100 * File to log connection info, statistics to.
101 */
102static struct GNUNET_DISK_FileHandle *data_file;
103
104/**
105 * How many data points to capture before triggering next round?
106 */
107static struct GNUNET_TIME_Relative wait_time;
108
109/**
110 * Task called to disconnect peers.
111 */
112static GNUNET_SCHEDULER_TaskIdentifier disconnect_task;
113
114/**
115 * Task To perform tests
116 */
117static GNUNET_SCHEDULER_TaskIdentifier test_task;
118
119/**
120 * Task called to shutdown test.
121 */
122static GNUNET_SCHEDULER_TaskIdentifier shutdown_handle;
123
124static char *topology_file;
125
126static char *data_filename;
127
128static struct GNUNET_TESTING_Daemon *d1;
129
130static GNUNET_PEER_Id pid1;
131
132static struct GNUNET_TESTING_Daemon *d2;
133
134static struct GNUNET_MESH_Handle *h1;
135
136static struct GNUNET_MESH_Handle *h2;
137
138static struct GNUNET_MESH_Tunnel *t;
139
140static struct GNUNET_MESH_Tunnel *incoming_t;
141
142static uint16_t *mesh_peers;
143
144/**
145 * Check whether peers successfully shut down.
146 */
147static void
148shutdown_callback (void *cls, const char *emsg)
149{
150 if (emsg != NULL)
151 {
152#if VERBOSE
153 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Shutdown of peers failed!\n");
154#endif
155 ok--;
156 }
157 else
158 {
159#if VERBOSE
160 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: All peers successfully shut down!\n");
161#endif
162 }
163}
164
165
166static void
167shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
168{
169#if VERBOSE
170 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Ending test.\n");
171#endif
172
173 if (disconnect_task != GNUNET_SCHEDULER_NO_TASK)
174 {
175 GNUNET_SCHEDULER_cancel (disconnect_task);
176 disconnect_task = GNUNET_SCHEDULER_NO_TASK;
177 }
178
179 if (data_file != NULL)
180 GNUNET_DISK_file_close (data_file);
181 GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL);
182 GNUNET_CONFIGURATION_destroy (testing_cfg);
183}
184
185
186static void
187disconnect_mesh_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
188{
189 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
190 "test: disconnecting mesh service of peers\n");
191 disconnect_task = GNUNET_SCHEDULER_NO_TASK;
192 GNUNET_MESH_disconnect(h1);
193 GNUNET_MESH_disconnect(h2);
194 GNUNET_SCHEDULER_cancel (shutdown_handle);
195 shutdown_handle = GNUNET_SCHEDULER_add_now(&shutdown_task, NULL);
196}
197
198
199/**
200 * Transmit ready callback
201 */
202size_t
203tmt_rdy (void *cls, size_t size, void *buf)
204{
205 struct GNUNET_MessageHeader *msg = buf;
206
207 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: tmt_rdy called\n");
208 if (size < sizeof(struct GNUNET_MessageHeader) || NULL == buf)
209 return 0;
210 msg->size = htons (sizeof(struct GNUNET_MessageHeader));
211 msg->type = htons ((long) cls);
212 return sizeof(struct GNUNET_MessageHeader);
213}
214
215
216/**
217 * Function is called whenever a message is received.
218 *
219 * @param cls closure (set from GNUNET_MESH_connect)
220 * @param tunnel connection to the other end
221 * @param tunnel_ctx place to store local state associated with the tunnel
222 * @param sender who sent the message
223 * @param message the actual message
224 * @param atsi performance data for the connection
225 * @return GNUNET_OK to keep the connection open,
226 * GNUNET_SYSERR to close it (signal serious error)
227 */
228int
229data_callback (void *cls,
230 struct GNUNET_MESH_Tunnel * tunnel,
231 void **tunnel_ctx,
232 const struct GNUNET_PeerIdentity *sender,
233 const struct GNUNET_MessageHeader *message,
234 const struct GNUNET_ATS_Information *atsi)
235{
236 long client = (long) cls;
237
238 switch (client)
239 {
240 case 1L:
241 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
242 "test: Origin client got a response!\n");
243 ok++;
244 GNUNET_MESH_tunnel_destroy (tunnel);
245 GNUNET_SCHEDULER_cancel (disconnect_task);
246 disconnect_task = GNUNET_SCHEDULER_add_delayed(SHORT_TIME,
247 &disconnect_mesh_peers,
248 NULL);
249 break;
250 case 2L:
251 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
252 "test: Destination client got a message \n");
253 ok++;
254 GNUNET_MESH_notify_transmit_ready(incoming_t,
255 GNUNET_NO,
256 0,
257 GNUNET_TIME_UNIT_FOREVER_REL,
258 sender,
259 sizeof(struct GNUNET_MessageHeader),
260 &tmt_rdy,
261 (void *) 1L);
262 GNUNET_SCHEDULER_cancel (disconnect_task);
263 disconnect_task = GNUNET_SCHEDULER_add_delayed(SHORT_TIME,
264 &disconnect_mesh_peers,
265 NULL);
266 break;
267 default:
268 break;
269 }
270 return GNUNET_OK;
271}
272
273
274/**
275 * Handlers, for diverse services
276 */
277static struct GNUNET_MESH_MessageHandler handlers[] = {
278 {&data_callback, 1, sizeof(struct GNUNET_MessageHeader)},
279 {NULL, 0, 0}
280};
281
282
283/**
284 * Method called whenever another peer has added us to a tunnel
285 * the other peer initiated.
286 *
287 * @param cls closure
288 * @param tunnel new handle to the tunnel
289 * @param initiator peer that started the tunnel
290 * @param atsi performance information for the tunnel
291 * @return initial tunnel context for the tunnel
292 * (can be NULL -- that's not an error)
293 */
294static void *
295incoming_tunnel (void *cls,
296 struct GNUNET_MESH_Tunnel * tunnel,
297 const struct GNUNET_PeerIdentity * initiator,
298 const struct GNUNET_ATS_Information * atsi)
299{
300 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
301 "test: Incoming tunnel from %s\n",
302 GNUNET_i2s(initiator));
303 ok++;
304 incoming_t = tunnel;
305 GNUNET_SCHEDULER_cancel (disconnect_task);
306 disconnect_task = GNUNET_SCHEDULER_add_delayed(SHORT_TIME,
307 &disconnect_mesh_peers,
308 NULL);
309 return NULL;
310}
311
312/**
313 * Function called whenever an inbound tunnel is destroyed. Should clean up
314 * any associated state.
315 *
316 * @param cls closure (set from GNUNET_MESH_connect)
317 * @param tunnel connection to the other end (henceforth invalid)
318 * @param tunnel_ctx place where local state associated
319 * with the tunnel is stored
320 */
321static void
322tunnel_cleaner (void *cls, const struct GNUNET_MESH_Tunnel *tunnel,
323 void *tunnel_ctx)
324{
325 long i = (long) cls;
326
327 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
328 "test: Incoming tunnel disconnected at peer %d\n",
329 i);
330 if (2L == i)
331 ok++;
332
333 GNUNET_SCHEDULER_cancel (disconnect_task);
334 disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_mesh_peers, NULL);
335
336 return;
337}
338
339
340/**
341 * Method called whenever a tunnel falls apart.
342 *
343 * @param cls closure
344 * @param peer peer identity the tunnel stopped working with
345 */
346static void
347dh (void *cls, const struct GNUNET_PeerIdentity *peer)
348{
349 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
350 "test: peer %s disconnected\n",
351 GNUNET_i2s(peer));
352 return;
353}
354
355
356/**
357 * Method called whenever a peer connects to a tunnel.
358 *
359 * @param cls closure
360 * @param peer peer identity the tunnel was created to, NULL on timeout
361 * @param atsi performance data for the connection
362 */
363static void
364ch (void *cls, const struct GNUNET_PeerIdentity *peer,
365 const struct GNUNET_ATS_Information *atsi)
366{
367 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
368 "test: peer %s connected\n",
369 GNUNET_i2s(peer));
370 if (0 == memcmp(&d2->id, peer, sizeof(d2->id)) && (long) cls == 1L)
371 ok++;
372 if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
373 {
374 GNUNET_SCHEDULER_cancel (disconnect_task);
375 disconnect_task = GNUNET_SCHEDULER_add_delayed(SHORT_TIME,
376 &disconnect_mesh_peers,
377 NULL);
378 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Sending data unicast...\n");
379 GNUNET_MESH_notify_transmit_ready(t,
380 GNUNET_NO,
381 0,
382 GNUNET_TIME_UNIT_FOREVER_REL,
383 &d2->id,
384 sizeof(struct GNUNET_MessageHeader),
385 &tmt_rdy,
386 (void *) 1L);
387 }
388 return;
389}
390
391
392static void
393do_test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
394{
395 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: test_task\n");
396 GNUNET_MESH_peer_request_connect_add(t, &d2->id);
397 GNUNET_SCHEDULER_cancel (disconnect_task);
398 disconnect_task = GNUNET_SCHEDULER_add_delayed(
399 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30),
400 &disconnect_mesh_peers, NULL);
401}
402
403
404/**
405 * Prototype of a callback function indicating that two peers
406 * are currently connected.
407 *
408 * @param cls closure
409 * @param first peer id for first daemon
410 * @param second peer id for the second daemon
411 * @param distance distance between the connected peers
412 * @param emsg error message (NULL on success)
413 */
414void
415topo_cb (void *cls,
416 const struct GNUNET_PeerIdentity* first,
417 const struct GNUNET_PeerIdentity* second,
418 const char *emsg)
419{
420 GNUNET_PEER_Id p1;
421 GNUNET_PEER_Id p2;
422 struct GNUNET_PeerIdentity id;
423
424 GNUNET_PEER_resolve(1, &id);
425 p1 = GNUNET_PEER_search(first);
426 if (p1 == pid1)
427 {
428 p2 = GNUNET_PEER_search(second);
429 GNUNET_assert(p2 < num_peers);
430 GNUNET_assert(p2 > 0);
431 mesh_peers[p2]++;
432 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
433 "test: %s IS a neighbor\n",
434 GNUNET_i2s(second));
435 return;
436 }
437 p1 = GNUNET_PEER_search(second);
438 if (p1 == pid1)
439 {
440 p2 = GNUNET_PEER_search(first);
441 GNUNET_assert(p2 < num_peers);
442 GNUNET_assert(p2 > 0);
443 mesh_peers[p2]++;
444 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
445 "test: %s IS a neighbor\n",
446 GNUNET_i2s(first));
447 return;
448 }
449}
450
451/**
452 * connect_mesh_service: connect to the mesh service of one of the peers
453 *
454 */
455static void
456connect_mesh_service (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
457{
458 GNUNET_MESH_ApplicationType app;
459 unsigned int i;
460 struct GNUNET_PeerIdentity id;
461
462 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: connect_mesh_service\n");
463
464 for (i = 1; i <= num_peers; i++)
465 {
466 GNUNET_PEER_resolve(i, &id);
467 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
468 "test: peer %s has %u conns to d1\n",
469 GNUNET_i2s (&id),
470 mesh_peers[i]);
471 if (mesh_peers[i] == 0)
472 break;
473 }
474 GNUNET_assert (i < num_peers);
475 d2 = GNUNET_TESTING_daemon_get_by_id (pg, &id);
476 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
477 "test: Peer searched: %s\n",
478 GNUNET_i2s (&d2->id));
479 app = (GNUNET_MESH_ApplicationType) 0;
480
481#if VERBOSE
482 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
483 "test: connecting to mesh service of peer %s (%u)\n",
484 GNUNET_i2s (&d1->id),
485 mesh_peers[0]);
486 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
487 "test: connecting to mesh service of peer %s (%u)\n",
488 GNUNET_i2s (&d2->id),
489 i);
490#endif
491 h1 = GNUNET_MESH_connect (d1->cfg,
492 10,
493 (void *) 1L,
494 NULL,
495 &tunnel_cleaner,
496 handlers,
497 &app);
498 h2 = GNUNET_MESH_connect (d2->cfg,
499 10,
500 (void *) 2L,
501 &incoming_tunnel,
502 &tunnel_cleaner,
503 handlers,
504 &app);
505#if VERBOSE
506 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
507 "test: connected to mesh service of peer %s\n",
508 GNUNET_i2s (&d1->id));
509 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
510 "test: connected to mesh service of peer %s\n",
511 GNUNET_i2s (&d2->id));
512#endif
513 t = GNUNET_MESH_tunnel_create (h1, NULL, &ch, &dh, (void *) 1L);
514 test_task =
515 GNUNET_SCHEDULER_add_delayed(
516 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 6),
517 &do_test, NULL);
518}
519
520
521
522/**
523 * peergroup_ready: start test when all peers are connected
524 * @param cls closure
525 * @param emsg error message
526 */
527static void
528peergroup_ready (void *cls, const char *emsg)
529{
530 char *buf;
531 int buf_len;
532 unsigned int i;
533
534 if (emsg != NULL)
535 {
536 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
537 "test: Peergroup callback called with error, aborting test!\n");
538 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
539 "test: Error from testing: `%s'\n", emsg);
540 ok--;
541 GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL);
542 return;
543 }
544#if VERBOSE
545 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
546 "************************************************************\n");
547 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
548 "test: Peer Group started successfully!\n");
549 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
550 "test: Have %u connections\n",
551 total_connections);
552#endif
553
554 if (data_file != NULL)
555 {
556 buf = NULL;
557 buf_len = GNUNET_asprintf (&buf, "CONNECTIONS_0: %u\n", total_connections);
558 if (buf_len > 0)
559 GNUNET_DISK_file_write (data_file, buf, buf_len);
560 GNUNET_free (buf);
561 }
562 peers_running = GNUNET_TESTING_daemons_running (pg);
563 for (i = 0; i < num_peers; i++)
564 {
565 d1 = GNUNET_TESTING_daemon_get (pg, i);
566 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
567 "test: %u: %s\n",
568 GNUNET_PEER_intern(&d1->id),
569 GNUNET_i2s (&d1->id));
570 }
571 d1 = GNUNET_TESTING_daemon_get (pg, 0);
572 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
573 "test: Peer looking: %s\n",
574 GNUNET_i2s (&d1->id));
575 pid1 = GNUNET_PEER_intern(&d1->id);
576 mesh_peers[pid1] = 100;
577 GNUNET_TESTING_get_topology(pg, &topo_cb, NULL);
578
579 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(
580 GNUNET_TIME_UNIT_SECONDS,
581 4),
582 &connect_mesh_service,
583 NULL);
584 disconnect_task =
585 GNUNET_SCHEDULER_add_delayed (wait_time, &disconnect_mesh_peers, NULL);
586
587}
588
589
590/**
591 * Function that will be called whenever two daemons are connected by
592 * the testing library.
593 *
594 * @param cls closure
595 * @param first peer id for first daemon
596 * @param second peer id for the second daemon
597 * @param distance distance between the connected peers
598 * @param first_cfg config for the first daemon
599 * @param second_cfg config for the second daemon
600 * @param first_daemon handle for the first daemon
601 * @param second_daemon handle for the second daemon
602 * @param emsg error message (NULL on success)
603 */
604static void
605connect_cb (void *cls, const struct GNUNET_PeerIdentity *first,
606 const struct GNUNET_PeerIdentity *second, uint32_t distance,
607 const struct GNUNET_CONFIGURATION_Handle *first_cfg,
608 const struct GNUNET_CONFIGURATION_Handle *second_cfg,
609 struct GNUNET_TESTING_Daemon *first_daemon,
610 struct GNUNET_TESTING_Daemon *second_daemon, const char *emsg)
611{
612 if (emsg == NULL)
613 {
614 total_connections++;
615 }
616 else
617 {
618 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
619 "test: Problem with new connection (%s)\n",
620 emsg);
621 }
622
623}
624
625
626/**
627 * run: load configuration options and schedule test to run (start peergroup)
628 * @param cls closure
629 * @param args argv
630 * @param cfgfile configuration file name (can be NULL)
631 * @param cfg configuration handle
632 */
633static void
634run (void *cls, char *const *args, const char *cfgfile,
635 const struct GNUNET_CONFIGURATION_Handle *cfg)
636{
637 char *temp_str;
638 unsigned long long temp_wait;
639 struct GNUNET_TESTING_Host *hosts;
640
641 ok = 0;
642 testing_cfg = GNUNET_CONFIGURATION_dup (cfg);
643
644 GNUNET_log_setup ("test_mesh_small_unicast",
645#if VERBOSE
646 "DEBUG",
647#else
648 "WARNING",
649#endif
650 NULL);
651
652#if VERBOSE
653 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Starting daemons.\n");
654 GNUNET_CONFIGURATION_set_value_string (testing_cfg, "testing",
655 "use_progressbars", "YES");
656#endif
657
658 if (GNUNET_OK !=
659 GNUNET_CONFIGURATION_get_value_number (testing_cfg, "testing",
660 "num_peers", &num_peers))
661 {
662 GNUNET_assert (GNUNET_OK ==
663 GNUNET_CONFIGURATION_load (testing_cfg,
664 "test_mesh_small.conf"));
665 if (GNUNET_OK !=
666 GNUNET_CONFIGURATION_get_value_number (testing_cfg, "testing",
667 "num_peers", &num_peers))
668 {
669 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
670 "Option TESTING:NUM_PEERS is required!\n");
671 return;
672 }
673 }
674
675 mesh_peers = GNUNET_malloc (sizeof(GNUNET_PEER_Id) * (num_peers + 1));
676
677 if (GNUNET_OK !=
678 GNUNET_CONFIGURATION_get_value_number (testing_cfg, "test_mesh_small",
679 "wait_time", &temp_wait))
680 {
681 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
682 "Option test_mesh_small:wait_time is required!\n");
683 return;
684 }
685
686 if (GNUNET_OK !=
687 GNUNET_CONFIGURATION_get_value_string (testing_cfg, "testing",
688 "topology_output_file",
689 &topology_file))
690 {
691 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
692 "Option test_mesh_small:topology_output_file is required!\n");
693 return;
694 }
695
696 if (GNUNET_OK !=
697 GNUNET_CONFIGURATION_get_value_string (testing_cfg, "test_mesh_small",
698 "data_output_file",
699 &data_filename))
700 {
701 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
702 "Option test_mesh_small:data_output_file is required!\n");
703 return;
704 }
705
706 data_file =
707 GNUNET_DISK_file_open (data_filename,
708 GNUNET_DISK_OPEN_READWRITE |
709 GNUNET_DISK_OPEN_CREATE,
710 GNUNET_DISK_PERM_USER_READ |
711 GNUNET_DISK_PERM_USER_WRITE);
712 if (data_file == NULL)
713 {
714 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to open %s for output!\n",
715 data_filename);
716 GNUNET_free (data_filename);
717 }
718
719 wait_time =
720 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, temp_wait);
721
722 if (GNUNET_YES ==
723 GNUNET_CONFIGURATION_get_value_string (cfg, "test_mesh_small",
724 "output_file", &temp_str))
725 {
726 output_file =
727 GNUNET_DISK_file_open (temp_str,
728 GNUNET_DISK_OPEN_READWRITE |
729 GNUNET_DISK_OPEN_CREATE,
730 GNUNET_DISK_PERM_USER_READ |
731 GNUNET_DISK_PERM_USER_WRITE);
732 if (output_file == NULL)
733 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to open %s for output!\n",
734 temp_str);
735 }
736 GNUNET_free_non_null (temp_str);
737
738 hosts = GNUNET_TESTING_hosts_load (testing_cfg);
739
740 pg = GNUNET_TESTING_peergroup_start (testing_cfg, num_peers, TIMEOUT,
741 &connect_cb, &peergroup_ready, NULL,
742 hosts);
743 GNUNET_assert (pg != NULL);
744 shutdown_handle =
745 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_get_forever (),
746 &shutdown_task, NULL);
747}
748
749
750
751/**
752 * test_mesh_small command line options
753 */
754static struct GNUNET_GETOPT_CommandLineOption options[] = {
755 {'V', "verbose", NULL,
756 gettext_noop ("be verbose (print progress information)"),
757 0, &GNUNET_GETOPT_set_one, &verbose},
758 GNUNET_GETOPT_OPTION_END
759};
760
761
762/**
763 * Main: start test
764 */
765int
766main (int argc, char *argv[])
767{
768 GNUNET_PROGRAM_run (argc, argv, "test_mesh_small_unicast",
769 gettext_noop ("Test mesh unicast in a small network."),
770 options, &run, NULL);
771#if REMOVE_DIR
772 GNUNET_DISK_directory_remove ("/tmp/test_mesh_small_unicast");
773#endif
774 if (OK_GOAL != ok)
775 {
776 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
777 "test: FAILED! (%d/%d)\n",
778 ok, OK_GOAL);
779 return 1;
780 }
781 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: success\n");
782 return 0;
783}
784
785/* end of test_mesh_small_unicast.c */