remove never working setuid helper code from the build-system.
[oweals/gnunet.git] / src / transport / test_quota_compliance.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2009, 2010, 2011, 2016 GNUnet e.V.
4
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.
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      Affero General Public License for more details.
14
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/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 /**
21  * @file transport/test_quota_compliance.c
22  * @brief base test case for transport implementations
23  *
24  * This test case tests quota compliance both on transport level
25  */
26 #include "platform.h"
27 #include "gnunet_transport_service.h"
28 #include "gnunet_ats_service.h"
29 #include "gauger.h"
30 #include "transport-testing.h"
31
32 /**
33  * Testcase timeout
34  */
35 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 480)
36
37 #define DURATION GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 80)
38
39
40 static struct GNUNET_SCHEDULER_Task *measure_task;
41
42 static char *gen_cfgs[2];
43
44 static unsigned long long quota_in[] = { 10000, 10000 };
45
46 static unsigned long long quota_out[] = { 10000, 10000 };
47
48 static struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc;
49
50
51 /**
52  * Note that this value must not significantly exceed
53  * 'MAX_PENDING' in 'gnunet-service-transport.c', otherwise
54  * messages may be dropped even for a reliable transport.
55  */
56 #define TOTAL_MSGS (1024 * 32)
57
58 static unsigned long long total_bytes_recv;
59
60 static struct GNUNET_TIME_Absolute start_time;
61
62
63 static void
64 report ()
65 {
66   unsigned long long delta;
67   unsigned long long datarate;
68
69   delta = GNUNET_TIME_absolute_get_duration (start_time).rel_value_us;
70   if (0 == delta)
71     delta = 1;
72   datarate = (total_bytes_recv * 1000 * 1000) / delta;
73
74   fprintf (stderr,
75            "Throughput was %llu b/s\n",
76            datarate);
77   ccc->global_ret = GNUNET_OK;
78   if (datarate > 1.5 * quota_in[1])
79   {
80     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
81                 "Datarate of %llu b/s significantly higher than allowed inbound quota of %llu b/s\n",
82                 datarate,
83                 quota_in[1]);
84     ccc->global_ret = GNUNET_SYSERR;
85   }
86   if (datarate > 1.5 * quota_out[0])
87   {
88     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
89                 "Datarate of %llu b/s significantly higher than allowed outbound quota of %llu b/s\n",
90                 datarate,
91                 quota_out[0]);
92     ccc->global_ret = GNUNET_SYSERR;
93   }
94   if (GNUNET_OK == ccc->global_ret)
95   {
96     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
97                 "Datarate of %llu b/s complied to allowed outbound quota of %llu b/s and inbound quota of %llu b/s\n",
98                 datarate,
99                 quota_out[0],
100                 quota_in[1]);
101   }
102 }
103
104
105 static void
106 custom_shutdown (void *cls)
107 {
108   if (NULL != measure_task)
109   {
110     GNUNET_SCHEDULER_cancel (measure_task);
111     measure_task = NULL;
112   }
113   report ();
114 }
115
116
117 static size_t
118 get_size (unsigned int iter)
119 {
120   size_t ret;
121
122   ret = (iter * iter * iter) % 60000;
123   ret += sizeof(struct GNUNET_TRANSPORT_TESTING_TestMessage);
124   return ret;
125 }
126
127
128 static void
129 notify_receive (void *cls,
130                 struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver,
131                 const struct GNUNET_PeerIdentity *sender,
132                 const struct GNUNET_TRANSPORT_TESTING_TestMessage *hdr)
133 {
134   if (GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE != ntohs (hdr->header.type))
135     return;
136   total_bytes_recv += ntohs (hdr->header.size);
137
138   {
139     char *ps = GNUNET_strdup (GNUNET_i2s (&receiver->id));
140
141     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
142                 "Peer %u (`%s') got message %u of size %u from peer (`%s')\n",
143                 receiver->no,
144                 ps,
145                 ntohl (hdr->num),
146                 ntohs (hdr->header.size),
147                 GNUNET_i2s (sender));
148     GNUNET_free (ps);
149   }
150 }
151
152
153 static void
154 measure (void *cls)
155 {
156   static int counter;
157
158   measure_task = NULL;
159   counter++;
160   if ((DURATION.rel_value_us / 1000 / 1000LL) < counter)
161   {
162     fprintf (stderr, "%s", ".\n");
163     GNUNET_SCHEDULER_shutdown ();
164     return;
165   }
166   fprintf (stderr, "%s", ".");
167   measure_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
168                                                &measure,
169                                                NULL);
170 }
171
172
173 static void
174 start_task (void *cls)
175 {
176   static struct GNUNET_TRANSPORT_TESTING_SendClosure sc = {
177     .num_messages = TOTAL_MSGS,
178     .get_size_cb = &get_size
179   };
180
181   sc.ccc = ccc;
182   measure_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
183                                                &measure,
184                                                NULL);
185   start_time = GNUNET_TIME_absolute_get ();
186   GNUNET_SCHEDULER_add_now (&GNUNET_TRANSPORT_TESTING_simple_send,
187                             &sc);
188 }
189
190
191 static char *
192 generate_config (const char *cfg_file,
193                  unsigned long long quota_in,
194                  unsigned long long quota_out)
195 {
196   char *in_name;
197   char *out_name;
198   char *fname = NULL;
199   struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create ();
200
201   GNUNET_assert (GNUNET_OK ==
202                  GNUNET_CONFIGURATION_load (cfg,
203                                             cfg_file));
204   GNUNET_asprintf (&fname,
205                    "q_in_%llu_q_out_%llu_%s",
206                    quota_in,
207                    quota_out,
208                    cfg_file);
209   GNUNET_CONFIGURATION_set_value_string (cfg,
210                                          "PATHS",
211                                          "DEFAULTCONFIG",
212                                          fname);
213   for (int c = 0; c < GNUNET_NT_COUNT; c++)
214   {
215     GNUNET_asprintf (&in_name,
216                      "%s_QUOTA_IN",
217                      GNUNET_NT_to_string (c));
218     GNUNET_asprintf (&out_name,
219                      "%s_QUOTA_OUT",
220                      GNUNET_NT_to_string (c));
221     GNUNET_CONFIGURATION_set_value_number (cfg,
222                                            "ats",
223                                            in_name,
224                                            quota_in);
225     GNUNET_CONFIGURATION_set_value_number (cfg,
226                                            "ats",
227                                            out_name,
228                                            quota_out);
229     GNUNET_free (in_name);
230     GNUNET_free (out_name);
231   }
232   GNUNET_assert (GNUNET_OK ==
233                  GNUNET_CONFIGURATION_write (cfg,
234                                              fname));
235   GNUNET_CONFIGURATION_destroy (cfg);
236   return fname;
237 }
238
239
240 static int
241 check (void *cls,
242        struct GNUNET_TRANSPORT_TESTING_Handle *tth_,
243        const char *test_plugin_,
244        const char *test_name_,
245        unsigned int num_peers,
246        char *cfg_files[])
247 {
248   struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext my_ccc = {
249     .connect_continuation = &start_task,
250     .config_file = "test_quota_compliance_data.conf",
251     .rec = &notify_receive,
252     .nc = &GNUNET_TRANSPORT_TESTING_log_connect,
253     .nd = &GNUNET_TRANSPORT_TESTING_log_disconnect,
254     .shutdown_task = &custom_shutdown,
255     .timeout = TIMEOUT
256   };
257
258   ccc = &my_ccc;
259
260   if (NULL != strstr (test_name_,
261                       "asymmetric"))
262   {
263     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
264                 "Running asymmetric test with sending peer unlimited, receiving peer (in/out): %llu/%llu b/s \n",
265                 quota_in[1],
266                 quota_out[1]);
267     quota_out[0] = 1024 * 1024 * 1024;
268     quota_in[0] = 1024 * 1024 * 1024;
269   }
270   else
271   {
272     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
273                 "Running symmetric test with (in/out) %llu/%llu b/s \n",
274                 quota_in[1],
275                 quota_out[1]);
276   }
277   for (unsigned int i = 0; i < 2; i++)
278   {
279     gen_cfgs[i] = generate_config (cfg_files[i],
280                                    quota_in[i],
281                                    quota_out[i]);
282     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
283                 "Generated config file `%s'\n",
284                 gen_cfgs[i]);
285   }
286
287   return GNUNET_TRANSPORT_TESTING_connect_check (&my_ccc,
288                                                  tth_,
289                                                  test_plugin_,
290                                                  test_name_,
291                                                  num_peers,
292                                                  gen_cfgs);
293 }
294
295
296 int
297 main (int argc,
298       char *argv[])
299 {
300   if (GNUNET_OK !=
301       GNUNET_TRANSPORT_TESTING_main (2,
302                                      &check,
303                                      NULL))
304   {
305     GNUNET_break (0);
306     return 1;
307   }
308   for (unsigned int i = 0; i < 2; i++)
309   {
310     if ((NULL != gen_cfgs[i]) &&
311         (GNUNET_YES == GNUNET_DISK_file_test (gen_cfgs[i])))
312     {
313       GNUNET_DISK_directory_remove (gen_cfgs[i]);
314       GNUNET_free (gen_cfgs[i]);
315     }
316   }
317   return 0;
318 }
319
320
321 /* end of test_quota_compliance.c */