aboutsummaryrefslogtreecommitdiff
path: root/src/transport/test_transport_address_switch.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/test_transport_address_switch.c')
-rw-r--r--src/transport/test_transport_address_switch.c433
1 files changed, 0 insertions, 433 deletions
diff --git a/src/transport/test_transport_address_switch.c b/src/transport/test_transport_address_switch.c
deleted file mode 100644
index ce5117bd1..000000000
--- a/src/transport/test_transport_address_switch.c
+++ /dev/null
@@ -1,433 +0,0 @@
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_transport_address_switch.c
22 * @brief base test case for transport implementations
23 *
24 * This test case tests if peers can successfully switch addresses when
25 * connected for plugins supporting multiple addresses by monitoring transport's
26 * statistic values.
27 *
28 * This test starts 2 peers and connects them. When connected test messages
29 * are transmitted from peer 2 to peer 1. The test monitors transport's
30 * statistics values for information about address switch attempts.
31 *
32 * The test passes with success if one of the peers could successfully switch
33 * addresses in connected state and a test message was successfully transmitted
34 * after this switch.
35 *
36 * Since it is not possible to trigger an address switch from outside,
37 * the test returns "77" (skipped) when no address switching attempt
38 * takes place. It fails if an address switch attempt fails.
39 *
40 * NOTE: The test seems largely useless right now, as we simply NEVER
41 * switch addresses under the test conditions. However, it may be a
42 * good starting point for a future test. For now, it always times
43 * out and returns "77" (skipped), so we set the timeout suitably low.
44 */
45#include "platform.h"
46#include "gnunet_transport_service.h"
47#include "gnunet_ats_service.h"
48#include "transport-testing.h"
49
50
51/**
52 * Testcase timeout (set aggressively as we know this test doesn't work right now)
53 */
54#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
55
56
57static struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc;
58
59static struct GNUNET_SCHEDULER_Task *measure_task;
60
61
62/**
63 * Statistics we track per peer.
64 */
65struct PeerStats
66{
67 struct GNUNET_STATISTICS_Handle *stat;
68
69 unsigned int addresses_avail;
70
71 unsigned int switch_attempts;
72
73 unsigned int switch_success;
74
75 unsigned int switch_fail;
76};
77
78static struct PeerStats stats[2];
79
80/* Amount of data transferred since last switch attempt */
81static unsigned long long bytes_sent_after_switch;
82
83static unsigned long long bytes_recv_after_switch;
84
85
86static int
87stat_start_attempt_cb (void *cls,
88 const char *subsystem,
89 const char *name,
90 uint64_t value,
91 int is_persistent)
92{
93 struct PeerStats *stat = cls;
94
95 stat->switch_attempts++;
96 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Switch attempted (%p)", stat);
97 bytes_recv_after_switch = 0;
98 bytes_sent_after_switch = 0;
99
100 return GNUNET_OK;
101}
102
103
104static int
105stat_success_attempt_cb (void *cls,
106 const char *subsystem,
107 const char *name,
108 uint64_t value,
109 int is_persistent)
110{
111 struct PeerStats *stat = cls;
112
113 stat->switch_success++;
114 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Switch succeeded (%p)", stat);
115 return GNUNET_OK;
116}
117
118
119static int
120stat_fail_attempt_cb (void *cls,
121 const char *subsystem,
122 const char *name,
123 uint64_t value,
124 int is_persistent)
125{
126 struct PeerStats *stat = cls;
127
128 if (value == 0)
129 return GNUNET_OK;
130
131 stat->switch_fail++;
132 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Switch failed (%p)", stat);
133 return GNUNET_OK;
134}
135
136
137static int
138stat_addresses_available (void *cls,
139 const char *subsystem,
140 const char *name,
141 uint64_t value,
142 int is_persistent)
143{
144 struct PeerStats *stat = cls;
145
146 stat->addresses_avail++;
147 return GNUNET_OK;
148}
149
150
151/**
152 * List of statistics entries we care about.
153 */
154static struct WatchEntry
155{
156 /**
157 * Name of the statistic we watch.
158 */
159 const char *stat_name;
160
161 /**
162 * Handler to register;
163 */
164 GNUNET_STATISTICS_Iterator stat_handler;
165} watches[] =
166{ { "# Attempts to switch addresses", &stat_start_attempt_cb },
167 { "# Successful attempts to switch addresses", &stat_success_attempt_cb },
168 { "# Failed attempts to switch addresses (failed to send CONNECT CONT)",
169 &stat_fail_attempt_cb },
170 { "# Failed attempts to switch addresses (failed to send CONNECT)",
171 &stat_fail_attempt_cb },
172 { "# Failed attempts to switch addresses (no response)",
173 &stat_fail_attempt_cb },
174 { "# transport addresses", &stat_addresses_available },
175 { NULL, NULL } };
176
177
178static void
179custom_shutdown (void *cls)
180{
181 int result;
182
183 if (NULL != measure_task)
184 {
185 GNUNET_SCHEDULER_cancel (measure_task);
186 measure_task = NULL;
187 }
188 if (0 == stats[0].switch_attempts + stats[1].switch_attempts)
189 {
190 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
191 "Test did not work, as peers didn't switch (flawed testcase)!\n");
192 ccc->global_ret = 77;
193 }
194 else
195 {
196 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
197 "Fail (timeout)! No transmission after switch! Stopping peers\n");
198 ccc->global_ret = 77; /* GNUNET_SYSERR; */
199 }
200
201 /* stop statistics */
202 for (unsigned int i = 0; i < 2; i++)
203 {
204 if (NULL != stats[i].stat)
205 {
206 for (unsigned int j = 0; NULL != watches[j].stat_name; j++)
207 GNUNET_assert (GNUNET_OK ==
208 GNUNET_STATISTICS_watch_cancel (stats[i].stat,
209 "transport",
210 watches[j].stat_name,
211 watches[j].stat_handler,
212 &stats[i]));
213 GNUNET_STATISTICS_destroy (stats[i].stat, GNUNET_NO);
214 stats[i].stat = NULL;
215 }
216 }
217
218 result = 0;
219 fprintf (stderr, "\n");
220 if (stats[0].switch_attempts > 0)
221 {
222 fprintf (
223 stderr,
224 "Peer 1 tried %u times to switch and succeeded %u times, failed %u times\n",
225 stats[0].switch_attempts,
226 stats[0].switch_success,
227 stats[0].switch_fail);
228 if (stats[0].switch_success != stats[0].switch_attempts)
229 {
230 GNUNET_break (0);
231 result++;
232 }
233 }
234 else if (stats[0].addresses_avail > 1)
235 {
236 fprintf (stderr,
237 "Peer 1 had %u addresses available, but did not try to switch\n",
238 stats[0].addresses_avail);
239 }
240 if (stats[1].switch_attempts > 0)
241 {
242 fprintf (
243 stderr,
244 "Peer 2 tried %u times to switch and succeeded %u times, failed %u times\n",
245 stats[1].switch_attempts,
246 stats[1].switch_success,
247 stats[1].switch_fail);
248 if (stats[1].switch_success != stats[1].switch_attempts)
249 {
250 GNUNET_break (0);
251 result++;
252 }
253 }
254 else if (stats[1].addresses_avail > 1)
255 {
256 fprintf (stderr,
257 "Peer 2 had %u addresses available, but did not try to switch\n",
258 stats[1].addresses_avail);
259 }
260
261 if (((stats[0].switch_attempts > 0) || (stats[1].switch_attempts > 0)) &&
262 (bytes_sent_after_switch == 0))
263 {
264 fprintf (stderr, "No data sent after switching!\n");
265 GNUNET_break (0);
266 result++;
267 }
268 if (((stats[0].switch_attempts > 0) || (stats[1].switch_attempts > 0)) &&
269 (bytes_recv_after_switch == 0))
270 {
271 fprintf (stderr, "No data received after switching!\n");
272 GNUNET_break (0);
273 result++;
274 }
275#if 0
276 /* This test is not really expected to pass right now... */
277 if (0 != result)
278 ccc->global_ret = GNUNET_SYSERR;
279#endif
280}
281
282
283static void
284notify_receive (void *cls,
285 struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver,
286 const struct GNUNET_PeerIdentity *sender,
287 const struct GNUNET_TRANSPORT_TESTING_TestMessage *hdr)
288{
289 if (GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE != ntohs (hdr->header.type))
290 return;
291
292 {
293 char *ps = GNUNET_strdup (GNUNET_i2s (&receiver->id));
294
295 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
296 "Peer %u (`%s') got message %u of size %u from peer (`%s')\n",
297 receiver->no,
298 ps,
299 (uint32_t) ntohl (hdr->num),
300 ntohs (hdr->header.size),
301 GNUNET_i2s (sender));
302 GNUNET_free (ps);
303 }
304 if (((stats[0].switch_attempts >= 1) || (stats[1].switch_attempts >= 1)) &&
305 (stats[0].switch_attempts ==
306 stats[0].switch_fail + stats[0].switch_success) &&
307 (stats[1].switch_attempts ==
308 stats[1].switch_fail + stats[1].switch_success))
309 {
310 bytes_recv_after_switch += ntohs (hdr->header.size);
311 if ((bytes_sent_after_switch > 0) && (bytes_recv_after_switch > 0))
312 {
313 /* A peer switched addresses and sent and received data after the
314 * switch operations */
315 GNUNET_SCHEDULER_shutdown ();
316 }
317 }
318}
319
320
321static void
322notify_send (void *cls)
323{
324 static uint32_t cnt;
325
326 GNUNET_assert (
327 GNUNET_OK ==
328 GNUNET_TRANSPORT_TESTING_send (ccc->p[1],
329 ccc->p[0],
330 GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE,
331 GNUNET_TRANSPORT_TESTING_LARGE_MESSAGE_SIZE,
332 ++cnt,
333 &notify_send,
334 NULL));
335 if (((stats[0].switch_attempts >= 1) || (stats[1].switch_attempts >= 1)) &&
336 (stats[0].switch_attempts ==
337 stats[0].switch_fail + stats[0].switch_success) &&
338 (stats[1].switch_attempts ==
339 stats[1].switch_fail + stats[1].switch_success))
340 {
341 bytes_sent_after_switch += GNUNET_TRANSPORT_TESTING_LARGE_MESSAGE_SIZE;
342 }
343}
344
345
346static void
347progress_indicator (void *cls)
348{
349 static int counter;
350
351 measure_task = NULL;
352 counter++;
353 if ((TIMEOUT.rel_value_us / 1000 / 1000LL) < counter)
354 {
355 fprintf (stderr, "%s", ".\n");
356 }
357 else
358 {
359 fprintf (stderr, "%s", ".");
360 measure_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
361 &progress_indicator,
362 NULL);
363 }
364}
365
366
367static void
368connected_cb (void *cls)
369{
370 for (unsigned int i = 0; i < 2; i++)
371 {
372 stats[i].stat = GNUNET_STATISTICS_create ("transport", ccc->p[i]->cfg);
373 if (NULL == stats[i].stat)
374 {
375 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
376 "Fail! Could not create statistics for peers!\n");
377 ccc->global_ret = GNUNET_SYSERR;
378 GNUNET_SCHEDULER_shutdown ();
379 return;
380 }
381 for (unsigned int j = 0; NULL != watches[j].stat_name; j++)
382 {
383 GNUNET_STATISTICS_watch (stats[i].stat,
384 "transport",
385 watches[j].stat_name,
386 watches[j].stat_handler,
387 &stats[i]);
388 }
389 }
390 /* Show progress */
391 ccc->global_ret = GNUNET_OK;
392 measure_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
393 &progress_indicator,
394 NULL);
395 /* Peers are connected, start transmit test messages */
396 GNUNET_assert (
397 GNUNET_OK ==
398 GNUNET_TRANSPORT_TESTING_send (ccc->p[1],
399 ccc->p[0],
400 GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE,
401 GNUNET_TRANSPORT_TESTING_LARGE_MESSAGE_SIZE,
402 0,
403 &notify_send,
404 NULL));
405}
406
407
408int
409main (int argc, char *argv[])
410{
411 struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext my_ccc =
412 { .connect_continuation = &connected_cb,
413 .config_file = "test_transport_api_data.conf",
414 .rec = &notify_receive,
415 .nc = &GNUNET_TRANSPORT_TESTING_log_connect,
416 .shutdown_task = &custom_shutdown,
417 .timeout = TIMEOUT };
418
419 ccc = &my_ccc;
420 int ret;
421
422 ret = GNUNET_TRANSPORT_TESTING_main (2,
423 &GNUNET_TRANSPORT_TESTING_connect_check,
424 ccc);
425 if (77 == ret)
426 return 77;
427 if (GNUNET_OK != ret)
428 return 1;
429 return 0;
430}
431
432
433/* end of test_transport_address_switch.c */