2 This file is part of GNUnet.
3 Copyright (C) 2009, 2010, 2011, 2016 GNUnet e.V.
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., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
21 * @file transport/test_quota_compliance.c
22 * @brief base test case for transport implementations
24 * This test case tests quota compliance both on transport level
27 #include "gnunet_transport_service.h"
28 #include "gnunet_ats_service.h"
30 #include "transport-testing.h"
35 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120)
38 * How long until we give up on transmitting the message?
40 #define TIMEOUT_TRANSMIT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 20)
42 #define DURATION GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
45 static struct GNUNET_SCHEDULER_Task *measure_task;
47 struct GNUNET_TRANSPORT_TransmitHandle *th;
49 static char *gen_cfgs[2];
51 static unsigned long long quota_in[] = { 10000, 10000 };
53 static unsigned long long quota_out[] = { 10000, 10000 };
55 static struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc;
59 * Note that this value must not significantly exceed
60 * 'MAX_PENDING' in 'gnunet-service-transport.c', otherwise
61 * messages may be dropped even for a reliable transport.
63 #define TOTAL_MSGS (1024 * 2)
67 GNUNET_NETWORK_STRUCT_BEGIN
70 struct GNUNET_MessageHeader header;
72 uint32_t num GNUNET_PACKED;
74 GNUNET_NETWORK_STRUCT_END
76 static int msg_scheduled;
80 static unsigned long long total_bytes_sent;
82 static struct GNUNET_TIME_Absolute start_time;
88 unsigned long long delta;
89 unsigned long long datarate;
91 delta = GNUNET_TIME_absolute_get_duration (start_time).rel_value_us;
92 datarate = (total_bytes_sent * 1000 * 1000) / delta;
95 "Throughput was %llu b/s\n",
98 if (datarate > quota_in[1])
100 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
101 "Datarate of %llu b/s higher than allowed inbound quota of %llu b/s\n",
104 ccc->global_ret = GNUNET_SYSERR;
106 if (datarate > quota_out[0])
108 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
109 "Datarate of %llu b/s higher than allowed outbound quota of %llu b/s\n",
112 ccc->global_ret = GNUNET_SYSERR;
114 if (GNUNET_OK == ccc->global_ret)
116 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
117 "Datarate of %llu b/s complied to allowed outbound quota of %llu b/s and inbound quota of %llu b/s\n",
126 custom_shutdown (void *cls)
128 if (NULL != measure_task)
130 GNUNET_SCHEDULER_cancel (measure_task);
135 GNUNET_TRANSPORT_notify_transmit_ready_cancel (th);
143 get_size (unsigned int iter)
147 ret = (iter * iter * iter);
148 return sizeof (struct TestMessage) + (ret % 60000);
153 notify_receive (void *cls,
154 struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver,
155 const struct GNUNET_PeerIdentity *sender,
156 const struct GNUNET_MessageHeader *message)
158 const struct TestMessage *hdr;
160 hdr = (const struct TestMessage *) message;
161 if (MTYPE != ntohs (message->type))
165 char *ps = GNUNET_strdup (GNUNET_i2s (&receiver->id));
167 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
168 "Peer %u (`%s') got message %u of size %u from peer (`%s')\n",
172 ntohs (message->size),
173 GNUNET_i2s (sender));
180 notify_ready (void *cls,
186 struct TestMessage hdr;
193 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
194 "Timeout occurred while waiting for transmit_ready for message %u of %u\n",
195 msg_scheduled, TOTAL_MSGS);
196 GNUNET_SCHEDULER_shutdown ();
197 ccc->global_ret = GNUNET_SYSERR;
203 GNUNET_assert (size >= s);
204 GNUNET_assert (buf != NULL);
208 hdr.header.size = htons (s);
209 hdr.header.type = htons (MTYPE);
212 GNUNET_memcpy (&cbuf[ret], &hdr, sizeof (struct TestMessage));
213 ret += sizeof (struct TestMessage);
214 memset (&cbuf[ret], n, s - sizeof (struct TestMessage));
215 ret += s - sizeof (struct TestMessage);
220 char *receiver_s = GNUNET_strdup (GNUNET_i2s (&ccc->p[0]->id));
222 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
223 "Sending message %u of size %u from peer %u (`%4s') -> peer %u (`%s') !\n",
226 GNUNET_i2s (&ccc->p[1]->id),
229 GNUNET_free (receiver_s);
235 if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 16))
236 break; /* sometimes pack buffer full, sometimes not */
238 while (size - ret >= s);
242 th = GNUNET_TRANSPORT_notify_transmit_ready (ccc->p[1]->th,
252 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
253 "Returning total message block of size %u\n",
256 total_bytes_sent += ret;
259 FPRINTF (stderr, "%s", "\n");
260 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
261 "All messages sent\n");
268 notify_disconnect (void *cls,
269 struct GNUNET_TRANSPORT_TESTING_PeerContext *me,
270 const struct GNUNET_PeerIdentity *other)
272 GNUNET_TRANSPORT_TESTING_log_disconnect (cls,
277 GNUNET_TRANSPORT_notify_transmit_ready_cancel (th);
286 start_time = GNUNET_TIME_absolute_get ();
287 th = GNUNET_TRANSPORT_notify_transmit_ready (ccc->p[1]->th,
303 if ((DURATION.rel_value_us / 1000 / 1000LL) < counter)
305 FPRINTF (stderr, "%s", ".\n");
306 GNUNET_SCHEDULER_shutdown ();
309 FPRINTF (stderr, "%s", ".");
310 measure_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
317 start_task (void *cls)
319 measure_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
322 GNUNET_SCHEDULER_add_now (&sendtask,
328 generate_config (const char *cfg_file,
329 unsigned long long quota_in,
330 unsigned long long quota_out)
335 struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create ();
337 GNUNET_assert (GNUNET_OK ==
338 GNUNET_CONFIGURATION_load (cfg,
340 GNUNET_asprintf (&fname,
341 "q_in_%llu_q_out_%llu_%s",
345 GNUNET_CONFIGURATION_set_value_string (cfg,
349 for (int c = 0; c < GNUNET_ATS_NetworkTypeCount; c++)
351 GNUNET_asprintf (&in_name,
353 GNUNET_ATS_print_network_type (c));
354 GNUNET_asprintf (&out_name,
356 GNUNET_ATS_print_network_type (c));
357 GNUNET_CONFIGURATION_set_value_number (cfg,
361 GNUNET_CONFIGURATION_set_value_number (cfg,
365 GNUNET_free (in_name);
366 GNUNET_free (out_name);
368 GNUNET_assert (GNUNET_OK ==
369 GNUNET_CONFIGURATION_write (cfg,
371 GNUNET_CONFIGURATION_destroy (cfg);
378 struct GNUNET_TRANSPORT_TESTING_Handle *tth_,
379 const char *test_plugin_,
380 const char *test_name_,
381 unsigned int num_peers,
384 struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext my_ccc = {
385 .connect_continuation = &start_task,
386 .config_file = "test_quota_compliance_data.conf",
387 .rec = ¬ify_receive,
388 .nc = &GNUNET_TRANSPORT_TESTING_log_connect,
389 .nd = ¬ify_disconnect,
390 .shutdown_task = &custom_shutdown,
395 if (NULL != strstr (test_name_,
398 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
399 "Running asymmetric test with sending peer unlimited, receiving peer (in/out): %llu/%llu b/s \n",
402 quota_out[0] = 1024 * 1024 * 1024;
403 quota_in[0] = 1024 * 1024 * 1024;
407 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
408 "Running symmetric test with (in/out) %llu/%llu b/s \n",
412 for (unsigned int i=0;i<2;i++)
414 gen_cfgs[i] = generate_config (cfg_files[i],
417 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
418 "Generated config file `%s'\n",
422 return GNUNET_TRANSPORT_TESTING_connect_check (&my_ccc,
432 main (int argc, char *argv[])
435 GNUNET_TRANSPORT_TESTING_main (2,
442 for (unsigned int i=0;i<2;i++)
444 if ( (NULL != gen_cfgs[0]) &&
445 (GNUNET_YES == GNUNET_DISK_file_test (gen_cfgs[0])) )
447 GNUNET_DISK_directory_remove (gen_cfgs[0]);
448 GNUNET_free (gen_cfgs[0]);
455 /* end of test_quota_compliance.c */