2 This file is part of GNUnet.
3 Copyright (C) 2011, 2017 GNUnet e.V.
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
21 * @file cadet/test_cadet.c
23 * @author Christian Grothoff
24 * @brief Test for the cadet service using mq API.
28 #include "cadet_test_lib.h"
29 #include "gnunet_cadet_service.h"
30 #include "gnunet_statistics_service.h"
35 * Ugly workaround to unify data handlers on incoming and outgoing channels.
37 struct CadetTestChannelWrapper {
41 struct GNUNET_CADET_Channel *ch;
45 * How many messages to send by default.
47 #define TOTAL_PACKETS 500 /* Cannot exceed 64k! */
50 * How long until we give up on connecting the peers?
52 #define TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 120)
55 * Time to wait by default for stuff that should be rather fast.
57 #define SHORT_TIME GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 20)
60 * How fast do we send messages?
62 #define SEND_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 10)
65 * DIFFERENT TESTS TO RUN
77 * Which test are we running?
82 * String with test name
84 static char *test_name;
87 * Flag to send traffic leaf->root in speed tests to test BCK_ACK logic.
89 static int test_backwards = GNUNET_NO;
92 * How many packets to send.
94 static unsigned int total_packets;
97 * Time to wait for fast operations.
99 static struct GNUNET_TIME_Relative short_time;
102 * How many events have happened
107 * Number of events expected to conclude the test successfully.
112 * Size of each test packet's payload
114 static size_t size_payload = sizeof(uint32_t);
117 * Operation to get peer ids.
119 static struct GNUNET_TESTBED_Operation *t_op[2];
124 static struct GNUNET_PeerIdentity *p_id[2];
129 static struct GNUNET_HashCode port;
134 static unsigned int p_ids;
137 * Is the setup initialized?
139 static int initialized;
142 * Number of payload packes sent.
144 static int data_sent;
147 * Number of payload packets received.
149 static int data_received;
152 * Number of payload packed acknowledgements sent.
157 * Number of payload packed explicitly (app level) acknowledged.
159 static int ack_received;
162 * Total number of peers asked to run.
164 static unsigned long long peers_requested;
167 * Number of currently running peers (should be same as @c peers_requested).
169 static unsigned long long peers_running;
172 * Test context (to shut down).
174 struct GNUNET_CADET_TEST_Context *test_ctx;
177 * Task called to disconnect peers.
179 static struct GNUNET_SCHEDULER_Task *disconnect_task;
182 * Task called to reconnect peers.
184 static struct GNUNET_SCHEDULER_Task *reconnect_task;
187 * Task To perform tests
189 static struct GNUNET_SCHEDULER_Task *test_task;
192 * Task runnining #send_next_msg().
194 static struct GNUNET_SCHEDULER_Task *send_next_msg_task;
197 * Cadet handle for the root peer
199 static struct GNUNET_CADET_Handle *h1;
202 * Cadet handle for the first leaf peer
204 static struct GNUNET_CADET_Handle *h2;
207 * Channel handle for the root peer
209 static struct GNUNET_CADET_Channel *outgoing_ch;
212 * Channel handle for the dest peer
214 static struct GNUNET_CADET_Channel *incoming_ch;
217 * Time we started the data transmission (after channel has been established
220 static struct GNUNET_TIME_Absolute start_time;
225 static struct GNUNET_TESTBED_Peer **testbed_peers;
228 * Statistics operation handle.
230 static struct GNUNET_TESTBED_Operation *stats_op;
235 static unsigned int ka_sent;
238 * Keepalives received.
240 static unsigned int ka_received;
243 * How many messages were dropped by CADET because of full buffers?
245 static unsigned int msg_dropped;
248 /******************************************************************************/
251 /******************************************************************************/
255 * Get the channel considered as the "target" or "receiver", depending on
256 * the test type and size.
258 * @return Channel handle of the target client, either 0 (for backward tests)
259 * or the last peer in the line (for other tests).
261 static struct GNUNET_CADET_Channel *
264 if (SPEED == test && GNUNET_YES == test_backwards)
272 * Show the results of the test (banwidth acheived) and log them to GAUGER
277 static struct GNUNET_TIME_Absolute end_time;
278 static struct GNUNET_TIME_Relative total_time;
280 end_time = GNUNET_TIME_absolute_get();
281 total_time = GNUNET_TIME_absolute_get_difference(start_time, end_time);
283 "\nResults of test \"%s\"\n",
287 GNUNET_STRINGS_relative_time_to_string(total_time, GNUNET_YES));
289 "Test bandwidth: %f kb/s\n",
290 4 * total_packets * 1.0 / (total_time.rel_value_us / 1000)); // 4bytes * ms
292 "Test throughput: %f packets/s\n\n",
293 total_packets * 1000.0 / (total_time.rel_value_us / 1000)); // packets * ms
296 total_packets * 1000.0 / (total_time.rel_value_us / 1000),
302 * Disconnect from cadet services af all peers, call shutdown.
304 * @param cls Closure (line number from which termination was requested).
305 * @param tc Task Context.
308 disconnect_cadet_peers(void *cls)
310 long line = (long)cls;
312 disconnect_task = NULL;
313 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
314 "disconnecting cadet service of peers, called from line %ld\n",
316 for (unsigned int i = 0; i < 2; i++)
318 GNUNET_TESTBED_operation_done(t_op[i]);
320 if (NULL != outgoing_ch)
322 GNUNET_CADET_channel_destroy(outgoing_ch);
325 if (NULL != incoming_ch)
327 GNUNET_CADET_channel_destroy(incoming_ch);
330 GNUNET_CADET_TEST_cleanup(test_ctx);
331 GNUNET_SCHEDULER_shutdown();
336 * Shut down peergroup, clean up.
338 * @param cls Closure (unused).
339 * @param tc Task Context.
342 shutdown_task(void *cls)
344 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
346 if (NULL != send_next_msg_task)
348 GNUNET_SCHEDULER_cancel(send_next_msg_task);
349 send_next_msg_task = NULL;
351 if (NULL != test_task)
353 GNUNET_SCHEDULER_cancel(test_task);
356 if (NULL != disconnect_task)
358 GNUNET_SCHEDULER_cancel(disconnect_task);
360 GNUNET_SCHEDULER_add_now(&disconnect_cadet_peers,
367 * Stats callback. Finish the stats testbed operation and when all stats have
368 * been iterated, shutdown the test.
370 * @param cls Closure (line number from which termination was requested).
371 * @param op the operation that has been finished
372 * @param emsg error message in case the operation has failed; will be NULL if
373 * operation has executed successfully.
376 stats_cont(void *cls,
377 struct GNUNET_TESTBED_Operation *op,
380 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
381 "KA sent: %u, KA received: %u\n",
384 if ((KEEPALIVE == test || REOPEN == test) &&
385 ((ka_sent < 2) || (ka_sent > ka_received + 1)))
390 GNUNET_TESTBED_operation_done(stats_op);
392 if (NULL != disconnect_task)
393 GNUNET_SCHEDULER_cancel(disconnect_task);
394 disconnect_task = GNUNET_SCHEDULER_add_now(&disconnect_cadet_peers,
400 * Process statistic values.
402 * @param cls closure (line number, unused)
403 * @param peer the peer the statistic belong to
404 * @param subsystem name of subsystem that created the statistic
405 * @param name the name of the datum
406 * @param value the current value
407 * @param is_persistent #GNUNET_YES if the value is persistent, #GNUNET_NO if not
408 * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
411 stats_iterator(void *cls,
412 const struct GNUNET_TESTBED_Peer *peer,
413 const char *subsystem,
418 static const char *s_sent = "# keepalives sent";
419 static const char *s_recv = "# keepalives received";
420 static const char *rdrops = "# messages dropped due to full buffer";
421 static const char *cdrops = "# messages dropped due to slow client";
424 i = GNUNET_TESTBED_get_index(peer);
425 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "STATS PEER %u - %s [%s]: %llu\n", i,
426 subsystem, name, (unsigned long long)value);
427 if (0 == strncmp(s_sent, name, strlen(s_sent)) && 0 == i)
429 if (0 == strncmp(s_recv, name, strlen(s_recv)) && peers_requested - 1 == i)
431 if (0 == strncmp(rdrops, name, strlen(rdrops)))
432 msg_dropped += value;
433 if (0 == strncmp(cdrops, name, strlen(cdrops)))
434 msg_dropped += value;
441 * Task to gather all statistics.
443 * @param cls Closure (line from which the task was scheduled).
446 gather_stats_and_exit(void *cls)
450 disconnect_task = NULL;
451 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
452 "gathering statistics from line %ld\n",
454 if (NULL != outgoing_ch)
456 GNUNET_CADET_channel_destroy(outgoing_ch);
459 stats_op = GNUNET_TESTBED_get_statistics(peers_running,
470 * Send a message on the channel with the appropriate size and payload.
472 * Update the appropriate *_sent counter.
474 * @param channel Channel to send the message on.
477 send_test_message(struct GNUNET_CADET_Channel *channel);
480 * Check if payload is sane (size contains payload).
482 * @param cls should match #ch
483 * @param message The actual message.
484 * @return #GNUNET_OK to keep the channel open,
485 * #GNUNET_SYSERR to close it (signal serious error).
488 check_data(void *cls,
489 const struct GNUNET_MessageHeader *message);
492 * Function is called whenever a message is received.
494 * @param cls closure (set from GNUNET_CADET_connect(), peer number)
495 * @param message the actual message
498 handle_data(void *cls,
499 const struct GNUNET_MessageHeader *message);
502 * Function called whenever an MQ-channel is destroyed, unless the destruction
503 * was requested by #GNUNET_CADET_channel_destroy.
504 * It must NOT call #GNUNET_CADET_channel_destroy on the channel.
506 * It should clean up any associated state, including cancelling any pending
507 * transmission on this channel.
509 * @param cls Channel closure (channel wrapper).
510 * @param channel Connection to the other end (henceforth invalid).
513 disconnect_handler(void *cls,
514 const struct GNUNET_CADET_Channel *channel);
518 * Task to reconnect to other peer.
520 * @param cls Closure (line from which the task was scheduled).
523 reconnect_op(void *cls)
525 struct GNUNET_MQ_MessageHandler handlers[] = {
526 GNUNET_MQ_hd_var_size(data,
527 GNUNET_MESSAGE_TYPE_DUMMY,
528 struct GNUNET_MessageHeader,
530 GNUNET_MQ_handler_end()
533 struct CadetTestChannelWrapper *ch;
535 reconnect_task = NULL;
536 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
537 "reconnecting from line %ld\n",
539 if (NULL != outgoing_ch)
541 GNUNET_CADET_channel_destroy(outgoing_ch);
544 ch = GNUNET_new(struct CadetTestChannelWrapper);
545 outgoing_ch = GNUNET_CADET_channel_create(h1,
552 ch->ch = outgoing_ch;
553 send_test_message(outgoing_ch);
557 * Function called whenever an MQ-channel is destroyed, unless the destruction
558 * was requested by #GNUNET_CADET_channel_destroy.
559 * It must NOT call #GNUNET_CADET_channel_destroy on the channel.
561 * It should clean up any associated state, including cancelling any pending
562 * transmission on this channel.
564 * @param cls Channel closure (channel wrapper).
565 * @param channel Connection to the other end (henceforth invalid).
568 disconnect_handler(void *cls,
569 const struct GNUNET_CADET_Channel *channel)
571 struct CadetTestChannelWrapper *ch_w = cls;
573 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
574 "Channel disconnected at %d\n",
576 GNUNET_assert(ch_w->ch == channel);
577 if (channel == incoming_ch)
582 else if (outgoing_ch == channel)
584 if (P2P_SIGNAL == test)
591 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
592 "Unknown channel! %p\n",
594 if (NULL != disconnect_task && REOPEN != test)
596 GNUNET_SCHEDULER_cancel(disconnect_task);
598 GNUNET_SCHEDULER_add_now(&gather_stats_and_exit,
601 else if (NULL != reconnect_task && REOPEN == test)
603 GNUNET_SCHEDULER_cancel(reconnect_task);
605 GNUNET_SCHEDULER_add_now(&reconnect_op,
613 * Abort test: schedule disconnect and shutdown immediately
615 * @param line Line in the code the abort is requested from (__LINE__).
618 abort_test(long line)
620 if (NULL != disconnect_task)
622 GNUNET_SCHEDULER_cancel(disconnect_task);
623 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
624 "Aborting test from %ld\n",
627 GNUNET_SCHEDULER_add_now(&disconnect_cadet_peers,
634 * Send a message on the channel with the appropriate size and payload.
636 * Update the appropriate *_sent counter.
638 * @param channel Channel to send the message on.
641 send_test_message(struct GNUNET_CADET_Channel *channel)
643 struct GNUNET_MQ_Envelope *env;
644 struct GNUNET_MessageHeader *msg;
649 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
650 "Sending test message on channel %p\n",
653 if (GNUNET_NO == initialized)
655 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Sending INITIALIZER\n");
658 if (SPEED_ACK == test) // FIXME unify SPEED_ACK with an initializer
661 else if (SPEED == test || SPEED_ACK == test)
663 if (get_target_channel() == channel)
668 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
669 "Sending ACK %u [%d bytes]\n",
677 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
678 "Sending DATA %u [%d bytes]\n",
682 else if (FORWARD == test)
686 else if (P2P_SIGNAL == test)
690 else if (REOPEN == test)
694 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
695 "Sending DATA %u [%d bytes]\n",
702 env = GNUNET_MQ_msg_extra(msg, size, GNUNET_MESSAGE_TYPE_DUMMY);
704 data = (uint32_t *)&msg[1];
705 *data = htonl(payload);
706 GNUNET_MQ_send(GNUNET_CADET_get_mq(channel), env);
711 * Task to request a new data transmission in a SPEED test, without waiting
712 * for previous messages to be sent/arrrive.
714 * @param cls Closure (unused).
717 send_next_msg(void *cls)
719 struct GNUNET_CADET_Channel *channel;
721 send_next_msg_task = NULL;
722 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
723 "Sending next message: %d\n",
726 channel = GNUNET_YES == test_backwards ? incoming_ch : outgoing_ch;
727 GNUNET_assert(NULL != channel);
728 GNUNET_assert(SPEED == test);
729 send_test_message(channel);
730 if (data_sent < total_packets)
732 /* SPEED test: Send all messages as soon as possible */
733 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
734 "Scheduling message %d\n",
737 GNUNET_SCHEDULER_add_delayed(SEND_INTERVAL,
745 * Every few messages cancel the timeout task and re-schedule it again, to
746 * avoid timing out when traffic keeps coming.
748 * @param line Code line number to log if a timeout occurs.
751 reschedule_timeout_task(long line)
755 if (NULL != disconnect_task)
757 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
758 "reschedule timeout every 10 messages\n");
759 GNUNET_SCHEDULER_cancel(disconnect_task);
760 disconnect_task = GNUNET_SCHEDULER_add_delayed(short_time,
761 &gather_stats_and_exit,
769 * Check if payload is sane (size contains payload).
771 * @param cls should match #ch
772 * @param message The actual message.
773 * @return #GNUNET_OK to keep the channel open,
774 * #GNUNET_SYSERR to close it (signal serious error).
777 check_data(void *cls,
778 const struct GNUNET_MessageHeader *message)
780 return GNUNET_OK; /* all is well-formed */
785 * Function is called whenever a message is received.
787 * @param cls closure (set from GNUNET_CADET_connect(), peer number)
788 * @param message the actual message
791 handle_data(void *cls,
792 const struct GNUNET_MessageHeader *message)
794 struct CadetTestChannelWrapper *ch = cls;
795 struct GNUNET_CADET_Channel *channel = ch->ch;
801 GNUNET_CADET_receive_done(channel);
802 counter = get_target_channel() == channel ? &data_received : &ack_received;
804 reschedule_timeout_task((long)__LINE__);
806 if (channel == outgoing_ch)
808 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
809 "Root client got a message.\n");
811 else if (channel == incoming_ch)
813 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
814 "Leaf client got a message.\n");
818 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
819 "Unknown channel %p.\n",
824 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
828 data = (uint32_t *)&message[1];
829 payload = ntohl(*data);
830 if (payload == *counter)
832 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
833 " payload as expected: %u\n",
838 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
839 " payload %u, expected: %u\n",
843 if (GNUNET_NO == initialized)
845 initialized = GNUNET_YES;
846 start_time = GNUNET_TIME_absolute_get();
849 GNUNET_assert(incoming_ch == channel);
850 send_next_msg_task = GNUNET_SCHEDULER_add_now(&send_next_msg,
857 if (get_target_channel() == channel) /* Got "data" */
859 GNUNET_log(GNUNET_ERROR_TYPE_INFO, " received data %u\n", data_received);
860 if (SPEED != test || (ok_goal - 2) == ok)
863 send_test_message(channel);
868 if (data_received < total_packets)
874 if (SPEED_ACK == test || SPEED == test)
876 GNUNET_log(GNUNET_ERROR_TYPE_INFO, " received ack %u\n", ack_received);
878 send_test_message(channel);
879 if (ack_received < total_packets && SPEED != test)
881 if (ok == 2 && SPEED == test)
885 if (test == P2P_SIGNAL)
887 GNUNET_CADET_channel_destroy(incoming_ch);
892 GNUNET_CADET_channel_destroy(outgoing_ch);
900 * Method called whenever a peer connects to a port in MQ-based CADET.
902 * @param cls Closure from #GNUNET_CADET_open_port (peer # as long).
903 * @param channel New handle to the channel.
904 * @param source Peer that started this channel.
905 * @return Closure for the incoming @a channel. It's given to:
906 * - The #GNUNET_CADET_DisconnectEventHandler (given to
907 * #GNUNET_CADET_open_port) when the channel dies.
908 * - Each the #GNUNET_MQ_MessageCallback handlers for each message
909 * received on the @a channel.
912 connect_handler(void *cls,
913 struct GNUNET_CADET_Channel *channel,
914 const struct GNUNET_PeerIdentity *source)
916 struct CadetTestChannelWrapper *ch;
917 long peer = (long)cls;
919 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
920 "Incoming channel from %s to %ld: %p\n",
925 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
928 if (peer == peers_requested - 1)
930 if (NULL != incoming_ch)
932 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
933 "Duplicate incoming channel for client %lu\n",
937 incoming_ch = channel;
941 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
942 "Incoming channel for unexpected peer #%lu\n",
946 if (NULL != disconnect_task && REOPEN != test)
948 GNUNET_SCHEDULER_cancel(disconnect_task);
949 disconnect_task = GNUNET_SCHEDULER_add_delayed(short_time,
950 &gather_stats_and_exit,
953 else if ((NULL != disconnect_task) && (REOPEN == test))
955 GNUNET_SCHEDULER_cancel(disconnect_task);
956 disconnect_task = GNUNET_SCHEDULER_add_delayed(
957 GNUNET_TIME_relative_multiply(short_time, 2),
958 &gather_stats_and_exit,
962 if ((NULL != reconnect_task) && (REOPEN == test))
964 GNUNET_SCHEDULER_cancel(reconnect_task);
965 reconnect_task = GNUNET_SCHEDULER_add_delayed(short_time,
970 /* TODO: cannot return channel as-is, in order to unify the data handlers */
971 ch = GNUNET_new(struct CadetTestChannelWrapper);
979 * START THE TESTCASE ITSELF, AS WE ARE CONNECTED TO THE CADET SERVICES.
981 * Testcase continues when the root receives confirmation of connected peers,
982 * on callback function ch.
984 * @param cls Closure (unused).
987 start_test(void *cls)
989 struct GNUNET_MQ_MessageHandler handlers[] = {
990 GNUNET_MQ_hd_var_size(data,
991 GNUNET_MESSAGE_TYPE_DUMMY,
992 struct GNUNET_MessageHeader,
994 GNUNET_MQ_handler_end()
996 struct CadetTestChannelWrapper *ch;
999 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "start_test: %s\n", test_name);
1000 if (NULL != disconnect_task)
1002 GNUNET_SCHEDULER_cancel(disconnect_task);
1003 disconnect_task = NULL;
1006 if (SPEED_REL == test)
1011 ch = GNUNET_new(struct CadetTestChannelWrapper);
1012 outgoing_ch = GNUNET_CADET_channel_create(h1,
1017 &disconnect_handler,
1020 ch->ch = outgoing_ch;
1022 disconnect_task = GNUNET_SCHEDULER_add_delayed(short_time,
1023 &gather_stats_and_exit,
1025 if (KEEPALIVE == test)
1026 return; /* Don't send any data. */
1032 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1033 "Sending data initializer on channel %p...\n",
1035 send_test_message(outgoing_ch);
1038 reconnect_task = GNUNET_SCHEDULER_add_delayed(short_time,
1041 GNUNET_SCHEDULER_cancel(disconnect_task);
1042 disconnect_task = GNUNET_SCHEDULER_add_delayed(
1043 GNUNET_TIME_relative_multiply(short_time, 2),
1044 &gather_stats_and_exit,
1051 * Callback to be called when the requested peer information is available
1053 * @param cls the closure from GNUNET_TESTBED_peer_get_information()
1054 * @param op the operation this callback corresponds to
1055 * @param pinfo the result; will be NULL if the operation has failed
1056 * @param emsg error message if the operation has failed;
1057 * NULL if the operation is successfull
1061 struct GNUNET_TESTBED_Operation *op,
1062 const struct GNUNET_TESTBED_PeerInformation *pinfo,
1067 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1068 "ID callback for %ld\n",
1070 if ((NULL == pinfo) ||
1073 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1076 abort_test(__LINE__);
1079 p_id[i] = pinfo->result.id;
1080 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1082 GNUNET_i2s(p_id[i]));
1086 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1087 "Got all IDs, starting test\n");
1088 test_task = GNUNET_SCHEDULER_add_now(&start_test, NULL);
1093 * test main: start test when all peers are connected
1095 * @param cls Closure.
1096 * @param ctx Argument to give to GNUNET_CADET_TEST_cleanup on test end.
1097 * @param num_peers Number of peers that are running.
1098 * @param peers Array of peers.
1099 * @param cadets Handle to each of the CADETs of the peers.
1103 struct GNUNET_CADET_TEST_Context *ctx,
1104 unsigned int num_peers,
1105 struct GNUNET_TESTBED_Peer **peers,
1106 struct GNUNET_CADET_Handle **cadets)
1108 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "test main\n");
1111 peers_running = num_peers;
1112 GNUNET_assert(peers_running == peers_requested);
1113 testbed_peers = peers;
1115 h2 = cadets[num_peers - 1];
1116 disconnect_task = GNUNET_SCHEDULER_add_delayed(short_time,
1117 &disconnect_cadet_peers,
1119 GNUNET_SCHEDULER_add_shutdown(&shutdown_task,
1121 t_op[0] = GNUNET_TESTBED_peer_get_information(peers[0],
1122 GNUNET_TESTBED_PIT_IDENTITY,
1125 t_op[1] = GNUNET_TESTBED_peer_get_information(peers[num_peers - 1],
1126 GNUNET_TESTBED_PIT_IDENTITY,
1129 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "requested peer ids\n");
1137 main(int argc, char *argv[])
1139 static const struct GNUNET_HashCode *ports[2];
1140 struct GNUNET_MQ_MessageHandler handlers[] = {
1141 GNUNET_MQ_hd_var_size(data,
1142 GNUNET_MESSAGE_TYPE_DUMMY,
1143 struct GNUNET_MessageHeader,
1145 GNUNET_MQ_handler_end()
1147 const char *config_file;
1148 char port_id[] = "test port";
1149 struct GNUNET_GETOPT_CommandLineOption options[] = {
1150 GNUNET_GETOPT_option_relative_time('t',
1153 gettext_noop("set short timeout"),
1155 GNUNET_GETOPT_option_uint('m',
1158 gettext_noop("set number of messages to send"),
1161 GNUNET_GETOPT_OPTION_END
1165 initialized = GNUNET_NO;
1166 GNUNET_log_setup("test", "DEBUG", NULL);
1168 total_packets = TOTAL_PACKETS;
1169 short_time = SHORT_TIME;
1170 if (-1 == GNUNET_GETOPT_run(argv[0], options, argc, argv))
1172 fprintf(stderr, "test failed: problem with CLI parameters\n");
1176 config_file = "test_cadet.conf";
1177 GNUNET_CRYPTO_hash(port_id, sizeof(port_id), &port);
1179 /* Find out requested size */
1180 if (strstr(argv[0], "_2_") != NULL)
1182 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DIRECT CONNECTIONs\n");
1183 peers_requested = 2;
1185 else if (strstr(argv[0], "_5_") != NULL)
1187 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "5 PEER LINE\n");
1188 peers_requested = 5;
1190 else if (strstr(argv[0], "_6_") != NULL)
1192 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "6 PEER LINE\n");
1193 peers_requested = 6;
1197 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "SIZE UNKNOWN, USING 2\n");
1198 peers_requested = 2;
1201 /* Find out requested test */
1202 if (strstr(argv[0], "_forward") != NULL)
1204 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "FORWARD\n");
1206 test_name = "unicast";
1209 else if (strstr(argv[0], "_signal") != NULL)
1211 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "SIGNAL\n");
1213 test_name = "signal";
1216 else if (strstr(argv[0], "_speed_ack") != NULL)
1218 /* Test is supposed to generate the following callbacks:
1219 * 1 incoming channel (@dest)
1220 * total_packets received data packet (@dest)
1221 * total_packets received data packet (@orig)
1222 * 1 received channel destroy (@dest) FIXME #5818
1224 ok_goal = total_packets * 2 + 2;
1225 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "SPEED_ACK\n");
1227 test_name = "speed ack";
1229 else if (strstr(argv[0], "_speed") != NULL)
1231 /* Test is supposed to generate the following callbacks:
1232 * 1 incoming channel (@dest)
1233 * 1 initial packet (@dest)
1234 * total_packets received data packet (@dest)
1235 * 1 received data packet (@orig)
1236 * 1 received channel destroy (@dest) FIXME #5818
1238 ok_goal = total_packets + 4;
1239 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "SPEED\n");
1240 if (strstr(argv[0], "_reliable") != NULL)
1243 test_name = "speed reliable";
1244 config_file = "test_cadet_drop.conf";
1249 test_name = "speed";
1252 else if (strstr(argv[0], "_keepalive") != NULL)
1255 test_name = "keepalive";
1256 /* Test is supposed to generate the following callbacks:
1257 * 1 incoming channel (@dest)
1259 * 1 received channel destroy (@dest) FIXME #5818
1263 else if (strstr(argv[0], "_reopen") != NULL)
1266 test_name = "reopen";
1267 ///* Test is supposed to generate the following callbacks:
1268 // * 1 incoming channel (@dest)
1270 // * 1 received channel destroy (@dest) FIXME #5818
1276 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "UNKNOWN\n");
1281 if (strstr(argv[0], "backwards") != NULL)
1283 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "BACKWARDS (LEAF TO ROOT)\n");
1284 test_backwards = GNUNET_YES;
1285 GNUNET_asprintf(&test_name, "backwards %s", test_name);
1291 GNUNET_CADET_TEST_ruN("test_cadet_small",
1295 NULL, /* tmain cls */
1298 &disconnect_handler,
1301 if (NULL != strstr(argv[0], "_reliable"))
1302 msg_dropped = 0; /* dropped should be retransmitted */
1304 if (ok_goal > ok - msg_dropped)
1306 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "FAILED! (%d/%d)\n", ok, ok_goal);
1309 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "success\n");
1313 /* end of test_cadet.c */