diff options
Diffstat (limited to 'src/transport/test_transport_address_switch.c')
-rw-r--r-- | src/transport/test_transport_address_switch.c | 433 |
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 | |||
57 | static struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc; | ||
58 | |||
59 | static struct GNUNET_SCHEDULER_Task *measure_task; | ||
60 | |||
61 | |||
62 | /** | ||
63 | * Statistics we track per peer. | ||
64 | */ | ||
65 | struct 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 | |||
78 | static struct PeerStats stats[2]; | ||
79 | |||
80 | /* Amount of data transferred since last switch attempt */ | ||
81 | static unsigned long long bytes_sent_after_switch; | ||
82 | |||
83 | static unsigned long long bytes_recv_after_switch; | ||
84 | |||
85 | |||
86 | static int | ||
87 | stat_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 | |||
104 | static int | ||
105 | stat_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 | |||
119 | static int | ||
120 | stat_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 | |||
137 | static int | ||
138 | stat_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 | */ | ||
154 | static 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 | |||
178 | static void | ||
179 | custom_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 | |||
283 | static void | ||
284 | notify_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 | |||
321 | static void | ||
322 | notify_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 | ¬ify_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 | |||
346 | static void | ||
347 | progress_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 | |||
367 | static void | ||
368 | connected_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 | ¬ify_send, | ||
404 | NULL)); | ||
405 | } | ||
406 | |||
407 | |||
408 | int | ||
409 | main (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 = ¬ify_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 */ | ||