aboutsummaryrefslogtreecommitdiff
path: root/src/cadet/test_cadet.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cadet/test_cadet.c')
-rw-r--r--src/cadet/test_cadet.c953
1 files changed, 953 insertions, 0 deletions
diff --git a/src/cadet/test_cadet.c b/src/cadet/test_cadet.c
new file mode 100644
index 000000000..ac2661a86
--- /dev/null
+++ b/src/cadet/test_cadet.c
@@ -0,0 +1,953 @@
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 cadet/test_cadet.c
22 *
23 * @brief Test for the cadet service: retransmission of traffic.
24 */
25#include <stdio.h>
26#include "platform.h"
27#include "cadet_test_lib.h"
28#include "gnunet_cadet_service.h"
29#include "gnunet_statistics_service.h"
30#include <gauger.h>
31
32
33/**
34 * How namy messages to send
35 */
36#define TOTAL_PACKETS 100
37
38/**
39 * How long until we give up on connecting the peers?
40 */
41#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120)
42
43/**
44 * Time to wait for stuff that should be rather fast
45 */
46#define SHORT_TIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60)
47
48/**
49 * DIFFERENT TESTS TO RUN
50 */
51#define SETUP 0
52#define FORWARD 1
53#define KEEPALIVE 2
54#define SPEED 3
55#define SPEED_ACK 4
56#define SPEED_REL 8
57#define P2P_SIGNAL 10
58
59/**
60 * Which test are we running?
61 */
62static int test;
63
64/**
65 * String with test name
66 */
67char *test_name;
68
69/**
70 * Flag to send traffic leaf->root in speed tests to test BCK_ACK logic.
71 */
72static int test_backwards = GNUNET_NO;
73
74/**
75 * How many events have happened
76 */
77static int ok;
78
79/**
80 * Number of events expected to conclude the test successfully.
81 */
82int ok_goal;
83
84/**
85 * Size of each test packet
86 */
87size_t size_payload = sizeof (struct GNUNET_MessageHeader) + sizeof (uint32_t);
88
89/**
90 * Operation to get peer ids.
91 */
92struct GNUNET_TESTBED_Operation *t_op[2];
93
94/**
95 * Peer ids.
96 */
97struct GNUNET_PeerIdentity *p_id[2];
98
99/**
100 * Peer ids counter.
101 */
102unsigned int p_ids;
103
104/**
105 * Is the setup initialized?
106 */
107static int initialized;
108
109/**
110 * Number of payload packes sent
111 */
112static int data_sent;
113
114/**
115 * Number of payload packets received
116 */
117static int data_received;
118
119/**
120 * Number of payload packed explicitly (app level) acknowledged
121 */
122static int data_ack;
123
124/**
125 * Total number of currently running peers.
126 */
127static unsigned long long peers_running;
128
129/**
130 * Test context (to shut down).
131 */
132struct GNUNET_CADET_TEST_Context *test_ctx;
133
134/**
135 * Task called to disconnect peers.
136 */
137static GNUNET_SCHEDULER_TaskIdentifier disconnect_task;
138
139/**
140 * Task To perform tests
141 */
142static GNUNET_SCHEDULER_TaskIdentifier test_task;
143
144/**
145 * Task called to shutdown test.
146 */
147static GNUNET_SCHEDULER_TaskIdentifier shutdown_handle;
148
149/**
150 * Cadet handle for the root peer
151 */
152static struct GNUNET_CADET_Handle *h1;
153
154/**
155 * Cadet handle for the first leaf peer
156 */
157static struct GNUNET_CADET_Handle *h2;
158
159/**
160 * Channel handle for the root peer
161 */
162static struct GNUNET_CADET_Channel *ch;
163
164/**
165 * Channel handle for the dest peer
166 */
167static struct GNUNET_CADET_Channel *incoming_ch;
168
169/**
170 * Time we started the data transmission (after channel has been established
171 * and initilized).
172 */
173static struct GNUNET_TIME_Absolute start_time;
174
175/**
176 * Peers handle.
177 */
178static struct GNUNET_TESTBED_Peer **testbed_peers;
179
180/**
181 * Statistics operation handle.
182 */
183static struct GNUNET_TESTBED_Operation *stats_op;
184
185/**
186 * Keepalives sent.
187 */
188static unsigned int ka_sent;
189
190/**
191 * Keepalives received.
192 */
193static unsigned int ka_received;
194
195
196/**
197 * Show the results of the test (banwidth acheived) and log them to GAUGER
198 */
199static void
200show_end_data (void)
201{
202 static struct GNUNET_TIME_Absolute end_time;
203 static struct GNUNET_TIME_Relative total_time;
204
205 end_time = GNUNET_TIME_absolute_get();
206 total_time = GNUNET_TIME_absolute_get_difference(start_time, end_time);
207 FPRINTF (stderr, "\nResults of test \"%s\"\n", test_name);
208 FPRINTF (stderr, "Test time %s\n",
209 GNUNET_STRINGS_relative_time_to_string (total_time,
210 GNUNET_YES));
211 FPRINTF (stderr, "Test bandwidth: %f kb/s\n",
212 4 * TOTAL_PACKETS * 1.0 / (total_time.rel_value_us / 1000)); // 4bytes * ms
213 FPRINTF (stderr, "Test throughput: %f packets/s\n\n",
214 TOTAL_PACKETS * 1000.0 / (total_time.rel_value_us / 1000)); // packets * ms
215 GAUGER ("CADET", test_name,
216 TOTAL_PACKETS * 1000.0 / (total_time.rel_value_us / 1000),
217 "packets/s");
218}
219
220
221/**
222 * Shut down peergroup, clean up.
223 *
224 * @param cls Closure (unused).
225 * @param tc Task Context.
226 */
227static void
228shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
229{
230 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ending test.\n");
231 shutdown_handle = GNUNET_SCHEDULER_NO_TASK;
232}
233
234
235/**
236 * Disconnect from cadet services af all peers, call shutdown.
237 *
238 * @param cls Closure (unused).
239 * @param tc Task Context.
240 */
241static void
242disconnect_cadet_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
243{
244 long line = (long) cls;
245 unsigned int i;
246
247 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
248 "disconnecting cadet service of peers, called from line %ld\n",
249 line);
250 disconnect_task = GNUNET_SCHEDULER_NO_TASK;
251 for (i = 0; i < 2; i++)
252 {
253 GNUNET_TESTBED_operation_done (t_op[i]);
254 }
255 if (NULL != ch)
256 {
257 GNUNET_CADET_channel_destroy (ch);
258 ch = NULL;
259 }
260 if (NULL != incoming_ch)
261 {
262 GNUNET_CADET_channel_destroy (incoming_ch);
263 incoming_ch = NULL;
264 }
265 GNUNET_CADET_TEST_cleanup (test_ctx);
266 if (GNUNET_SCHEDULER_NO_TASK != shutdown_handle)
267 {
268 GNUNET_SCHEDULER_cancel (shutdown_handle);
269 }
270 shutdown_handle = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL);
271}
272
273
274/**
275 * Abort test: schedule disconnect and shutdown immediately
276 *
277 * @param line Line in the code the abort is requested from (__LINE__).
278 */
279static void
280abort_test (long line)
281{
282 if (disconnect_task != GNUNET_SCHEDULER_NO_TASK)
283 {
284 GNUNET_SCHEDULER_cancel (disconnect_task);
285 disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_cadet_peers,
286 (void *) line);
287 }
288}
289
290/**
291 * Transmit ready callback.
292 *
293 * @param cls Closure (message type).
294 * @param size Size of the tranmist buffer.
295 * @param buf Pointer to the beginning of the buffer.
296 *
297 * @return Number of bytes written to buf.
298 */
299static size_t
300tmt_rdy (void *cls, size_t size, void *buf);
301
302
303/**
304 * Task to schedule a new data transmission.
305 *
306 * @param cls Closure (peer #).
307 * @param tc Task Context.
308 */
309static void
310data_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
311{
312 struct GNUNET_CADET_TransmitHandle *th;
313 struct GNUNET_CADET_Channel *channel;
314
315 if ((GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason) != 0)
316 return;
317
318 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Data task\n");
319 if (GNUNET_YES == test_backwards)
320 {
321 channel = incoming_ch;
322 }
323 else
324 {
325 channel = ch;
326 }
327 th = GNUNET_CADET_notify_transmit_ready (channel, GNUNET_NO,
328 GNUNET_TIME_UNIT_FOREVER_REL,
329 size_payload, &tmt_rdy, (void *) 1L);
330 if (NULL == th)
331 {
332 unsigned long i = (unsigned long) cls;
333
334 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Retransmission\n");
335 if (0 == i)
336 {
337 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " in 1 ms\n");
338 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS,
339 &data_task, (void *)1UL);
340 }
341 else
342 {
343 i++;
344 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "in %u ms\n", i);
345 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(
346 GNUNET_TIME_UNIT_MILLISECONDS,
347 i),
348 &data_task, (void *)i);
349 }
350 }
351}
352
353
354/**
355 * Transmit ready callback
356 *
357 * @param cls Closure (message type).
358 * @param size Size of the buffer we have.
359 * @param buf Buffer to copy data to.
360 */
361size_t
362tmt_rdy (void *cls, size_t size, void *buf)
363{
364 struct GNUNET_MessageHeader *msg = buf;
365 uint32_t *data;
366
367 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
368 "tmt_rdy called, filling buffer\n");
369 if (size < size_payload || NULL == buf)
370 {
371 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
372 "size %u, buf %p, data_sent %u, data_received %u\n",
373 size, buf, data_sent, data_received);
374 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ok %u, ok goal %u\n", ok, ok_goal);
375 GNUNET_break (ok >= ok_goal - 2);
376
377 return 0;
378 }
379 msg->size = htons (size);
380 msg->type = htons ((long) cls);
381 data = (uint32_t *) &msg[1];
382 *data = htonl (data_sent);
383 if (GNUNET_NO == initialized)
384 {
385 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
386 "sending initializer\n");
387 }
388 else if (SPEED == test)
389 {
390 data_sent++;
391 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
392 " Sent packet %d\n", data_sent);
393 if (data_sent < TOTAL_PACKETS)
394 {
395 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
396 " Scheduling packet %d\n", data_sent + 1);
397 GNUNET_SCHEDULER_add_now (&data_task, NULL);
398 }
399 }
400
401 return size_payload;
402}
403
404
405/**
406 * Function is called whenever a message is received.
407 *
408 * @param cls closure (set from GNUNET_CADET_connect)
409 * @param channel connection to the other end
410 * @param channel_ctx place to store local state associated with the channel
411 * @param message the actual message
412 * @return GNUNET_OK to keep the connection open,
413 * GNUNET_SYSERR to close it (signal serious error)
414 */
415int
416data_callback (void *cls, struct GNUNET_CADET_Channel *channel,
417 void **channel_ctx,
418 const struct GNUNET_MessageHeader *message)
419{
420 long client = (long) cls;
421 long expected_target_client;
422 uint32_t *data;
423
424 ok++;
425
426 GNUNET_CADET_receive_done (channel);
427
428 if ((ok % 20) == 0)
429 {
430 if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
431 {
432 GNUNET_SCHEDULER_cancel (disconnect_task);
433 disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
434 &disconnect_cadet_peers,
435 (void *) __LINE__);
436 }
437 }
438
439 switch (client)
440 {
441 case 0L:
442 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Root client got a message!\n");
443 break;
444 case 4L:
445 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
446 "Leaf client %li got a message.\n",
447 client);
448 break;
449 default:
450 GNUNET_assert (0);
451 break;
452 }
453 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: (%d/%d)\n", ok, ok_goal);
454 data = (uint32_t *) &message[1];
455 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " payload: (%u)\n", ntohl (*data));
456 if (SPEED == test && GNUNET_YES == test_backwards)
457 {
458 expected_target_client = 0L;
459 }
460 else
461 {
462 expected_target_client = 4L;
463 }
464
465 if (GNUNET_NO == initialized)
466 {
467 initialized = GNUNET_YES;
468 start_time = GNUNET_TIME_absolute_get ();
469 if (SPEED == test)
470 {
471 GNUNET_assert (4L == client);
472 GNUNET_SCHEDULER_add_now (&data_task, NULL);
473 return GNUNET_OK;
474 }
475 }
476
477 if (client == expected_target_client) // Normally 4
478 {
479 data_received++;
480 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " received data %u\n", data_received);
481 if (SPEED != test || (ok_goal - 2) == ok)
482 {
483 GNUNET_CADET_notify_transmit_ready (channel, GNUNET_NO,
484 GNUNET_TIME_UNIT_FOREVER_REL,
485 size_payload, &tmt_rdy, (void *) 1L);
486 return GNUNET_OK;
487 }
488 else
489 {
490 if (data_received < TOTAL_PACKETS)
491 return GNUNET_OK;
492 }
493 }
494 else // Normally 0
495 {
496 if (test == SPEED_ACK || test == SPEED)
497 {
498 data_ack++;
499 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " received ack %u\n", data_ack);
500 GNUNET_CADET_notify_transmit_ready (channel, GNUNET_NO,
501 GNUNET_TIME_UNIT_FOREVER_REL,
502 size_payload, &tmt_rdy, (void *) 1L);
503 if (data_ack < TOTAL_PACKETS && SPEED != test)
504 return GNUNET_OK;
505 if (ok == 2 && SPEED == test)
506 return GNUNET_OK;
507 show_end_data();
508 }
509 if (test == P2P_SIGNAL)
510 {
511 GNUNET_CADET_channel_destroy (incoming_ch);
512 incoming_ch = NULL;
513 }
514 else
515 {
516 GNUNET_CADET_channel_destroy (ch);
517 ch = NULL;
518 }
519 }
520
521 if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
522 {
523 GNUNET_SCHEDULER_cancel (disconnect_task);
524 disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
525 &disconnect_cadet_peers,
526 (void *) __LINE__);
527 }
528
529 return GNUNET_OK;
530}
531
532
533/**
534 * Stats callback. Finish the stats testbed operation and when all stats have
535 * been iterated, shutdown the test.
536 *
537 * @param cls closure
538 * @param op the operation that has been finished
539 * @param emsg error message in case the operation has failed; will be NULL if
540 * operation has executed successfully.
541 */
542static void
543stats_cont (void *cls, struct GNUNET_TESTBED_Operation *op, const char *emsg)
544{
545 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "stats_cont for peer %u\n", cls);
546 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " sent: %u, received: %u\n",
547 ka_sent, ka_received);
548 if (ka_sent < 2 || ka_sent > ka_received + 1)
549 ok--;
550 GNUNET_TESTBED_operation_done (stats_op);
551
552 if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
553 GNUNET_SCHEDULER_cancel (disconnect_task);
554 disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_cadet_peers,
555 (void *) __LINE__);
556
557}
558
559
560/**
561 * Process statistic values.
562 *
563 * @param cls closure
564 * @param peer the peer the statistic belong to
565 * @param subsystem name of subsystem that created the statistic
566 * @param name the name of the datum
567 * @param value the current value
568 * @param is_persistent GNUNET_YES if the value is persistent, GNUNET_NO if not
569 * @return GNUNET_OK to continue, GNUNET_SYSERR to abort iteration
570 */
571static int
572stats_iterator (void *cls, const struct GNUNET_TESTBED_Peer *peer,
573 const char *subsystem, const char *name,
574 uint64_t value, int is_persistent)
575{
576 static const char *s_sent = "# keepalives sent";
577 static const char *s_recv = "# keepalives received";
578 uint32_t i;
579
580 i = GNUNET_TESTBED_get_index (peer);
581 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %u - %s [%s]: %llu\n",
582 i, subsystem, name, value);
583 if (0 == strncmp (s_sent, name, strlen (s_sent)) && 0 == i)
584 ka_sent = value;
585
586 if (0 == strncmp(s_recv, name, strlen (s_recv)) && 4 == i)
587 ka_received = value;
588
589 return GNUNET_OK;
590}
591
592
593/**
594 * Task check that keepalives were sent and received.
595 *
596 * @param cls Closure (NULL).
597 * @param tc Task Context.
598 */
599static void
600check_keepalives (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
601{
602 if ((GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason) != 0)
603 return;
604
605 disconnect_task = GNUNET_SCHEDULER_NO_TASK;
606 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "check keepalives\n");
607 GNUNET_CADET_channel_destroy (ch);
608 stats_op = GNUNET_TESTBED_get_statistics (5, testbed_peers,
609 "cadet", NULL,
610 stats_iterator, stats_cont, NULL);
611}
612
613
614/**
615 * Handlers, for diverse services
616 */
617static struct GNUNET_CADET_MessageHandler handlers[] = {
618 {&data_callback, 1, sizeof (struct GNUNET_MessageHeader)},
619 {NULL, 0, 0}
620};
621
622
623/**
624 * Method called whenever another peer has added us to a channel
625 * the other peer initiated.
626 *
627 * @param cls Closure.
628 * @param channel New handle to the channel.
629 * @param initiator Peer that started the channel.
630 * @param port Port this channel is connected to.
631 * @param options channel option flags
632 * @return Initial channel context for the channel
633 * (can be NULL -- that's not an error).
634 */
635static void *
636incoming_channel (void *cls, struct GNUNET_CADET_Channel *channel,
637 const struct GNUNET_PeerIdentity *initiator,
638 uint32_t port, enum GNUNET_CADET_ChannelOption options)
639{
640 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
641 "Incoming channel from %s to peer %d\n",
642 GNUNET_i2s (initiator), (long) cls);
643 ok++;
644 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: %d\n", ok);
645 if ((long) cls == 4L)
646 incoming_ch = channel;
647 else
648 {
649 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
650 "Incoming channel for unknown client %lu\n", (long) cls);
651 GNUNET_break(0);
652 }
653 if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
654 {
655 GNUNET_SCHEDULER_cancel (disconnect_task);
656 if (KEEPALIVE == test)
657 {
658 struct GNUNET_TIME_Relative delay;
659 delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS , 5);
660 disconnect_task =
661 GNUNET_SCHEDULER_add_delayed (delay, &check_keepalives, NULL);
662 }
663 else
664 disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
665 &disconnect_cadet_peers,
666 (void *) __LINE__);
667 }
668
669 return NULL;
670}
671
672/**
673 * Function called whenever an inbound channel is destroyed. Should clean up
674 * any associated state.
675 *
676 * @param cls closure (set from GNUNET_CADET_connect)
677 * @param channel connection to the other end (henceforth invalid)
678 * @param channel_ctx place where local state associated
679 * with the channel is stored
680 */
681static void
682channel_cleaner (void *cls, const struct GNUNET_CADET_Channel *channel,
683 void *channel_ctx)
684{
685 long i = (long) cls;
686
687 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
688 "Incoming channel disconnected at peer %ld\n", i);
689 if (4L == i)
690 {
691 ok++;
692 GNUNET_break (channel == incoming_ch);
693 incoming_ch = NULL;
694 }
695 else if (0L == i)
696 {
697 if (P2P_SIGNAL == test)
698 {
699 ok ++;
700 }
701 GNUNET_break (channel == ch);
702 ch = NULL;
703 }
704 else
705 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
706 "Unknown peer! %d\n", i);
707 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: %d\n", ok);
708
709 if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
710 {
711 GNUNET_SCHEDULER_cancel (disconnect_task);
712 disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_cadet_peers,
713 (void *) __LINE__);
714 }
715
716 return;
717}
718
719
720/**
721 * START THE TESTCASE ITSELF, AS WE ARE CONNECTED TO THE CADET SERVICES.
722 *
723 * Testcase continues when the root receives confirmation of connected peers,
724 * on callback funtion ch.
725 *
726 * @param cls Closure (unsued).
727 * @param tc Task Context.
728 */
729static void
730do_test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
731{
732 enum GNUNET_CADET_ChannelOption flags;
733
734 if ((GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason) != 0)
735 return;
736
737 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test_task\n");
738
739 if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
740 {
741 GNUNET_SCHEDULER_cancel (disconnect_task);
742 }
743
744 flags = GNUNET_CADET_OPTION_DEFAULT;
745 if (SPEED_REL == test)
746 {
747 test = SPEED;
748 flags |= GNUNET_CADET_OPTION_RELIABLE;
749 }
750 ch = GNUNET_CADET_channel_create (h1, NULL, p_id[1], 1, flags);
751
752 disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
753 &disconnect_cadet_peers,
754 (void *) __LINE__);
755 if (KEEPALIVE == test)
756 return; /* Don't send any data. */
757
758 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
759 "Sending data initializer...\n");
760 data_ack = 0;
761 data_received = 0;
762 data_sent = 0;
763 GNUNET_CADET_notify_transmit_ready (ch, GNUNET_NO,
764 GNUNET_TIME_UNIT_FOREVER_REL,
765 size_payload, &tmt_rdy, (void *) 1L);
766}
767
768/**
769 * Callback to be called when the requested peer information is available
770 *
771 * @param cls the closure from GNUNET_TESTBED_peer_get_information()
772 * @param op the operation this callback corresponds to
773 * @param pinfo the result; will be NULL if the operation has failed
774 * @param emsg error message if the operation has failed;
775 * NULL if the operation is successfull
776 */
777static void
778pi_cb (void *cls,
779 struct GNUNET_TESTBED_Operation *op,
780 const struct GNUNET_TESTBED_PeerInformation *pinfo,
781 const char *emsg)
782{
783 long i = (long) cls;
784
785 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "id callback for %ld\n", i);
786
787 if (NULL == pinfo || NULL != emsg)
788 {
789 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "pi_cb: %s\n", emsg);
790 abort_test (__LINE__);
791 return;
792 }
793 p_id[i] = pinfo->result.id;
794 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " id: %s\n", GNUNET_i2s (p_id[i]));
795 p_ids++;
796 if (p_ids < 2)
797 return;
798 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got all IDs, starting test\n");
799 test_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
800 &do_test, NULL);
801}
802
803/**
804 * test main: start test when all peers are connected
805 *
806 * @param cls Closure.
807 * @param ctx Argument to give to GNUNET_CADET_TEST_cleanup on test end.
808 * @param num_peers Number of peers that are running.
809 * @param peers Array of peers.
810 * @param cadetes Handle to each of the CADETs of the peers.
811 */
812static void
813tmain (void *cls,
814 struct GNUNET_CADET_TEST_Context *ctx,
815 unsigned int num_peers,
816 struct GNUNET_TESTBED_Peer **peers,
817 struct GNUNET_CADET_Handle **cadetes)
818{
819 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test main\n");
820 ok = 0;
821 test_ctx = ctx;
822 peers_running = num_peers;
823 testbed_peers = peers;
824 h1 = cadetes[0];
825 h2 = cadetes[num_peers - 1];
826 disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
827 &disconnect_cadet_peers,
828 (void *) __LINE__);
829 shutdown_handle = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
830 &shutdown_task, NULL);
831 t_op[0] = GNUNET_TESTBED_peer_get_information (peers[0],
832 GNUNET_TESTBED_PIT_IDENTITY,
833 &pi_cb, (void *) 0L);
834 t_op[1] = GNUNET_TESTBED_peer_get_information (peers[num_peers - 1],
835 GNUNET_TESTBED_PIT_IDENTITY,
836 &pi_cb, (void *) 1L);
837 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "requested peer ids\n");
838}
839
840
841/**
842 * Main: start test
843 */
844int
845main (int argc, char *argv[])
846{
847 initialized = GNUNET_NO;
848 static uint32_t ports[2];
849 const char *config_file;
850
851 GNUNET_log_setup ("test", "DEBUG", NULL);
852 config_file = "test_cadet.conf";
853
854 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start\n");
855 if (strstr (argv[0], "_cadet_forward") != NULL)
856 {
857 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "FORWARD\n");
858 test = FORWARD;
859 test_name = "unicast";
860 ok_goal = 4;
861 }
862 else if (strstr (argv[0], "_cadet_signal") != NULL)
863 {
864 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "SIGNAL\n");
865 test = P2P_SIGNAL;
866 test_name = "signal";
867 ok_goal = 4;
868 }
869 else if (strstr (argv[0], "_cadet_speed_ack") != NULL)
870 {
871 /* Test is supposed to generate the following callbacks:
872 * 1 incoming channel (@dest)
873 * TOTAL_PACKETS received data packet (@dest)
874 * TOTAL_PACKETS received data packet (@orig)
875 * 1 received channel destroy (@dest)
876 */
877 ok_goal = TOTAL_PACKETS * 2 + 2;
878 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "SPEED_ACK\n");
879 test = SPEED_ACK;
880 test_name = "speed ack";
881 }
882 else if (strstr (argv[0], "_cadet_speed") != NULL)
883 {
884 /* Test is supposed to generate the following callbacks:
885 * 1 incoming channel (@dest)
886 * 1 initial packet (@dest)
887 * TOTAL_PACKETS received data packet (@dest)
888 * 1 received data packet (@orig)
889 * 1 received channel destroy (@dest)
890 */
891 ok_goal = TOTAL_PACKETS + 4;
892 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "SPEED\n");
893 if (strstr (argv[0], "_reliable") != NULL)
894 {
895 test = SPEED_REL;
896 test_name = "speed reliable";
897 config_file = "test_cadet_drop.conf";
898 }
899 else
900 {
901 test = SPEED;
902 test_name = "speed";
903 }
904 }
905 else if (strstr (argv[0], "_keepalive") != NULL)
906 {
907 test = KEEPALIVE;
908 /* Test is supposed to generate the following callbacks:
909 * 1 incoming channel (@dest)
910 * [wait]
911 * 1 received channel destroy (@dest)
912 */
913 ok_goal = 2;
914 }
915 else
916 {
917 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "UNKNOWN\n");
918 test = SETUP;
919 ok_goal = 0;
920 }
921
922 if (strstr (argv[0], "backwards") != NULL)
923 {
924 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "BACKWARDS (LEAF TO ROOT)\n");
925 test_backwards = GNUNET_YES;
926 GNUNET_asprintf (&test_name, "backwards %s", test_name);
927 }
928
929 p_ids = 0;
930 ports[0] = 1;
931 ports[1] = 0;
932 GNUNET_CADET_TEST_run ("test_cadet_small",
933 config_file,
934 5,
935 &tmain,
936 NULL, /* tmain cls */
937 &incoming_channel,
938 &channel_cleaner,
939 handlers,
940 ports);
941
942 if (ok_goal > ok)
943 {
944 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
945 "FAILED! (%d/%d)\n", ok, ok_goal);
946 return 1;
947 }
948 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "success\n");
949 return 0;
950}
951
952/* end of test_cadet.c */
953