2 This file is part of GNUnet.
3 (C) 2011 Christian Grothoff (and other contributing authors)
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.
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.
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.
21 * @file cadet/test_cadet.c
23 * @brief Test for the cadet service: retransmission of traffic.
27 #include "cadet_test_lib.h"
28 #include "gnunet_cadet_service.h"
29 #include "gnunet_statistics_service.h"
34 * How namy messages to send
36 #define TOTAL_PACKETS 100
39 * How long until we give up on connecting the peers?
41 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120)
44 * Time to wait for stuff that should be rather fast
46 #define SHORT_TIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60)
49 * DIFFERENT TESTS TO RUN
60 * Which test are we running?
65 * String with test name
70 * Flag to send traffic leaf->root in speed tests to test BCK_ACK logic.
72 static int test_backwards = GNUNET_NO;
75 * How many events have happened
80 * Number of events expected to conclude the test successfully.
85 * Size of each test packet
87 size_t size_payload = sizeof (struct GNUNET_MessageHeader) + sizeof (uint32_t);
90 * Operation to get peer ids.
92 struct GNUNET_TESTBED_Operation *t_op[2];
97 struct GNUNET_PeerIdentity *p_id[2];
105 * Is the setup initialized?
107 static int initialized;
110 * Number of payload packes sent
112 static int data_sent;
115 * Number of payload packets received
117 static int data_received;
120 * Number of payload packed explicitly (app level) acknowledged
125 * Total number of currently running peers.
127 static unsigned long long peers_running;
130 * Test context (to shut down).
132 struct GNUNET_CADET_TEST_Context *test_ctx;
135 * Task called to disconnect peers.
137 static GNUNET_SCHEDULER_TaskIdentifier disconnect_task;
140 * Task To perform tests
142 static GNUNET_SCHEDULER_TaskIdentifier test_task;
145 * Task called to shutdown test.
147 static GNUNET_SCHEDULER_TaskIdentifier shutdown_handle;
150 * Cadet handle for the root peer
152 static struct GNUNET_CADET_Handle *h1;
155 * Cadet handle for the first leaf peer
157 static struct GNUNET_CADET_Handle *h2;
160 * Channel handle for the root peer
162 static struct GNUNET_CADET_Channel *ch;
165 * Channel handle for the dest peer
167 static struct GNUNET_CADET_Channel *incoming_ch;
170 * Time we started the data transmission (after channel has been established
173 static struct GNUNET_TIME_Absolute start_time;
178 static struct GNUNET_TESTBED_Peer **testbed_peers;
181 * Statistics operation handle.
183 static struct GNUNET_TESTBED_Operation *stats_op;
188 static unsigned int ka_sent;
191 * Keepalives received.
193 static unsigned int ka_received;
197 * Show the results of the test (banwidth acheived) and log them to GAUGER
202 static struct GNUNET_TIME_Absolute end_time;
203 static struct GNUNET_TIME_Relative total_time;
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,
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),
222 * Shut down peergroup, clean up.
224 * @param cls Closure (unused).
225 * @param tc Task Context.
228 shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
230 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ending test.\n");
231 shutdown_handle = GNUNET_SCHEDULER_NO_TASK;
236 * Disconnect from cadet services af all peers, call shutdown.
238 * @param cls Closure (unused).
239 * @param tc Task Context.
242 disconnect_cadet_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
244 long line = (long) cls;
247 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
248 "disconnecting cadet service of peers, called from line %ld\n",
250 disconnect_task = GNUNET_SCHEDULER_NO_TASK;
251 for (i = 0; i < 2; i++)
253 GNUNET_TESTBED_operation_done (t_op[i]);
257 GNUNET_CADET_channel_destroy (ch);
260 if (NULL != incoming_ch)
262 GNUNET_CADET_channel_destroy (incoming_ch);
265 GNUNET_CADET_TEST_cleanup (test_ctx);
266 if (GNUNET_SCHEDULER_NO_TASK != shutdown_handle)
268 GNUNET_SCHEDULER_cancel (shutdown_handle);
270 shutdown_handle = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL);
275 * Abort test: schedule disconnect and shutdown immediately
277 * @param line Line in the code the abort is requested from (__LINE__).
280 abort_test (long line)
282 if (disconnect_task != GNUNET_SCHEDULER_NO_TASK)
284 GNUNET_SCHEDULER_cancel (disconnect_task);
285 disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_cadet_peers,
291 * Transmit ready callback.
293 * @param cls Closure (message type).
294 * @param size Size of the tranmist buffer.
295 * @param buf Pointer to the beginning of the buffer.
297 * @return Number of bytes written to buf.
300 tmt_rdy (void *cls, size_t size, void *buf);
304 * Task to schedule a new data transmission.
306 * @param cls Closure (peer #).
307 * @param tc Task Context.
310 data_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
312 struct GNUNET_CADET_TransmitHandle *th;
313 struct GNUNET_CADET_Channel *channel;
315 if ((GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason) != 0)
318 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Data task\n");
319 if (GNUNET_YES == test_backwards)
321 channel = incoming_ch;
327 th = GNUNET_CADET_notify_transmit_ready (channel, GNUNET_NO,
328 GNUNET_TIME_UNIT_FOREVER_REL,
329 size_payload, &tmt_rdy, (void *) 1L);
332 unsigned long i = (unsigned long) cls;
334 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Retransmission\n");
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);
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,
348 &data_task, (void *)i);
355 * Transmit ready callback
357 * @param cls Closure (message type).
358 * @param size Size of the buffer we have.
359 * @param buf Buffer to copy data to.
362 tmt_rdy (void *cls, size_t size, void *buf)
364 struct GNUNET_MessageHeader *msg = buf;
367 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
368 "tmt_rdy called, filling buffer\n");
369 if (size < size_payload || NULL == buf)
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);
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)
385 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
386 "sending initializer\n");
388 else if (SPEED == test)
391 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
392 " Sent packet %d\n", data_sent);
393 if (data_sent < TOTAL_PACKETS)
395 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
396 " Scheduling packet %d\n", data_sent + 1);
397 GNUNET_SCHEDULER_add_now (&data_task, NULL);
406 * Function is called whenever a message is received.
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)
416 data_callback (void *cls, struct GNUNET_CADET_Channel *channel,
418 const struct GNUNET_MessageHeader *message)
420 long client = (long) cls;
421 long expected_target_client;
426 GNUNET_CADET_receive_done (channel);
430 if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
432 GNUNET_SCHEDULER_cancel (disconnect_task);
433 disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
434 &disconnect_cadet_peers,
442 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Root client got a message!\n");
445 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
446 "Leaf client %li got a message.\n",
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)
458 expected_target_client = 0L;
462 expected_target_client = 4L;
465 if (GNUNET_NO == initialized)
467 initialized = GNUNET_YES;
468 start_time = GNUNET_TIME_absolute_get ();
471 GNUNET_assert (4L == client);
472 GNUNET_SCHEDULER_add_now (&data_task, NULL);
477 if (client == expected_target_client) // Normally 4
480 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " received data %u\n", data_received);
481 if (SPEED != test || (ok_goal - 2) == ok)
483 GNUNET_CADET_notify_transmit_ready (channel, GNUNET_NO,
484 GNUNET_TIME_UNIT_FOREVER_REL,
485 size_payload, &tmt_rdy, (void *) 1L);
490 if (data_received < TOTAL_PACKETS)
496 if (test == SPEED_ACK || test == SPEED)
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)
505 if (ok == 2 && SPEED == test)
509 if (test == P2P_SIGNAL)
511 GNUNET_CADET_channel_destroy (incoming_ch);
516 GNUNET_CADET_channel_destroy (ch);
521 if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
523 GNUNET_SCHEDULER_cancel (disconnect_task);
524 disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
525 &disconnect_cadet_peers,
534 * Stats callback. Finish the stats testbed operation and when all stats have
535 * been iterated, shutdown the test.
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.
543 stats_cont (void *cls, struct GNUNET_TESTBED_Operation *op, const char *emsg)
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)
550 GNUNET_TESTBED_operation_done (stats_op);
552 if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
553 GNUNET_SCHEDULER_cancel (disconnect_task);
554 disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_cadet_peers,
561 * Process statistic values.
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
572 stats_iterator (void *cls, const struct GNUNET_TESTBED_Peer *peer,
573 const char *subsystem, const char *name,
574 uint64_t value, int is_persistent)
576 static const char *s_sent = "# keepalives sent";
577 static const char *s_recv = "# keepalives received";
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)
586 if (0 == strncmp(s_recv, name, strlen (s_recv)) && 4 == i)
594 * Task check that keepalives were sent and received.
596 * @param cls Closure (NULL).
597 * @param tc Task Context.
600 check_keepalives (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
602 if ((GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason) != 0)
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,
610 stats_iterator, stats_cont, NULL);
615 * Handlers, for diverse services
617 static struct GNUNET_CADET_MessageHandler handlers[] = {
618 {&data_callback, 1, sizeof (struct GNUNET_MessageHeader)},
624 * Method called whenever another peer has added us to a channel
625 * the other peer initiated.
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).
636 incoming_channel (void *cls, struct GNUNET_CADET_Channel *channel,
637 const struct GNUNET_PeerIdentity *initiator,
638 uint32_t port, enum GNUNET_CADET_ChannelOption options)
640 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
641 "Incoming channel from %s to peer %d\n",
642 GNUNET_i2s (initiator), (long) cls);
644 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: %d\n", ok);
645 if ((long) cls == 4L)
646 incoming_ch = channel;
649 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
650 "Incoming channel for unknown client %lu\n", (long) cls);
653 if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
655 GNUNET_SCHEDULER_cancel (disconnect_task);
656 if (KEEPALIVE == test)
658 struct GNUNET_TIME_Relative delay;
659 delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS , 5);
661 GNUNET_SCHEDULER_add_delayed (delay, &check_keepalives, NULL);
664 disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
665 &disconnect_cadet_peers,
673 * Function called whenever an inbound channel is destroyed. Should clean up
674 * any associated state.
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
682 channel_cleaner (void *cls, const struct GNUNET_CADET_Channel *channel,
687 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
688 "Incoming channel disconnected at peer %ld\n", i);
692 GNUNET_break (channel == incoming_ch);
697 if (P2P_SIGNAL == test)
701 GNUNET_break (channel == ch);
705 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
706 "Unknown peer! %d\n", i);
707 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: %d\n", ok);
709 if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
711 GNUNET_SCHEDULER_cancel (disconnect_task);
712 disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_cadet_peers,
721 * START THE TESTCASE ITSELF, AS WE ARE CONNECTED TO THE CADET SERVICES.
723 * Testcase continues when the root receives confirmation of connected peers,
724 * on callback funtion ch.
726 * @param cls Closure (unsued).
727 * @param tc Task Context.
730 do_test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
732 enum GNUNET_CADET_ChannelOption flags;
734 if ((GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason) != 0)
737 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test_task\n");
739 if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
741 GNUNET_SCHEDULER_cancel (disconnect_task);
744 flags = GNUNET_CADET_OPTION_DEFAULT;
745 if (SPEED_REL == test)
748 flags |= GNUNET_CADET_OPTION_RELIABLE;
750 ch = GNUNET_CADET_channel_create (h1, NULL, p_id[1], 1, flags);
752 disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
753 &disconnect_cadet_peers,
755 if (KEEPALIVE == test)
756 return; /* Don't send any data. */
758 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
759 "Sending data initializer...\n");
763 GNUNET_CADET_notify_transmit_ready (ch, GNUNET_NO,
764 GNUNET_TIME_UNIT_FOREVER_REL,
765 size_payload, &tmt_rdy, (void *) 1L);
769 * Callback to be called when the requested peer information is available
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
779 struct GNUNET_TESTBED_Operation *op,
780 const struct GNUNET_TESTBED_PeerInformation *pinfo,
785 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "id callback for %ld\n", i);
787 if (NULL == pinfo || NULL != emsg)
789 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "pi_cb: %s\n", emsg);
790 abort_test (__LINE__);
793 p_id[i] = pinfo->result.id;
794 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " id: %s\n", GNUNET_i2s (p_id[i]));
798 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got all IDs, starting test\n");
799 test_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
804 * test main: start test when all peers are connected
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.
814 struct GNUNET_CADET_TEST_Context *ctx,
815 unsigned int num_peers,
816 struct GNUNET_TESTBED_Peer **peers,
817 struct GNUNET_CADET_Handle **cadetes)
819 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test main\n");
822 peers_running = num_peers;
823 testbed_peers = peers;
825 h2 = cadetes[num_peers - 1];
826 disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
827 &disconnect_cadet_peers,
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");
845 main (int argc, char *argv[])
847 initialized = GNUNET_NO;
848 static uint32_t ports[2];
849 const char *config_file;
851 GNUNET_log_setup ("test", "DEBUG", NULL);
852 config_file = "test_cadet.conf";
854 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start\n");
855 if (strstr (argv[0], "_cadet_forward") != NULL)
857 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "FORWARD\n");
859 test_name = "unicast";
862 else if (strstr (argv[0], "_cadet_signal") != NULL)
864 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "SIGNAL\n");
866 test_name = "signal";
869 else if (strstr (argv[0], "_cadet_speed_ack") != NULL)
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)
877 ok_goal = TOTAL_PACKETS * 2 + 2;
878 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "SPEED_ACK\n");
880 test_name = "speed ack";
882 else if (strstr (argv[0], "_cadet_speed") != NULL)
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)
891 ok_goal = TOTAL_PACKETS + 4;
892 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "SPEED\n");
893 if (strstr (argv[0], "_reliable") != NULL)
896 test_name = "speed reliable";
897 config_file = "test_cadet_drop.conf";
905 else if (strstr (argv[0], "_keepalive") != NULL)
908 /* Test is supposed to generate the following callbacks:
909 * 1 incoming channel (@dest)
911 * 1 received channel destroy (@dest)
917 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "UNKNOWN\n");
922 if (strstr (argv[0], "backwards") != NULL)
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);
932 GNUNET_CADET_TEST_run ("test_cadet_small",
936 NULL, /* tmain cls */
944 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
945 "FAILED! (%d/%d)\n", ok, ok_goal);
948 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "success\n");
952 /* end of test_cadet.c */