aboutsummaryrefslogtreecommitdiff
path: root/src/transport/transport-testing-main2.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/transport-testing-main2.c')
-rw-r--r--src/transport/transport-testing-main2.c614
1 files changed, 0 insertions, 614 deletions
diff --git a/src/transport/transport-testing-main2.c b/src/transport/transport-testing-main2.c
deleted file mode 100644
index 0a1710922..000000000
--- a/src/transport/transport-testing-main2.c
+++ /dev/null
@@ -1,614 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 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-testing-main.c
22 * @brief convenience main function for tests
23 * @author Christian Grothoff
24 */
25#include "platform.h"
26#include "transport-testing2.h"
27
28
29/**
30 * Closure for #connect_cb.
31 */
32struct GNUNET_TRANSPORT_TESTING_ConnectRequestList
33{
34 /**
35 * Stored in a DLL.
36 */
37 struct GNUNET_TRANSPORT_TESTING_ConnectRequestList *next;
38
39 /**
40 * Stored in a DLL.
41 */
42 struct GNUNET_TRANSPORT_TESTING_ConnectRequestList *prev;
43
44 /**
45 * Overall context we are in.
46 */
47 struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc;
48
49 /**
50 * Connect request this is about.
51 */
52 struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cr;
53
54 /**
55 * Peer being connected.
56 */
57 struct GNUNET_TRANSPORT_TESTING_PeerContext *p1;
58
59 /**
60 * Peer being connected.
61 */
62 struct GNUNET_TRANSPORT_TESTING_PeerContext *p2;
63};
64
65
66/**
67 * Shutdown function for the test. Stops all peers.
68 *
69 * @param cls our `struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *`
70 */
71static void
72do_shutdown (void *cls)
73{
74 struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = cls;
75 struct GNUNET_TRANSPORT_TESTING_ConnectRequestList *crl;
76
77 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
78 "Testcase shutting down\n");
79 if (NULL != ccc->shutdown_task)
80 ccc->shutdown_task (ccc->shutdown_task_cls);
81 if (NULL != ccc->timeout_task)
82 {
83 GNUNET_SCHEDULER_cancel (ccc->timeout_task);
84 ccc->timeout_task = NULL;
85 }
86 if (NULL != ccc->connect_task)
87 {
88 GNUNET_SCHEDULER_cancel (ccc->connect_task);
89 ccc->connect_task = NULL;
90 }
91 while (NULL != (crl = ccc->crl_head))
92 {
93 GNUNET_CONTAINER_DLL_remove (ccc->crl_head,
94 ccc->crl_tail,
95 crl);
96 GNUNET_TRANSPORT_TESTING_connect_peers_cancel (crl->cr);
97 GNUNET_free (crl);
98 }
99 for (unsigned int i = 0; i < ccc->num_peers; i++)
100 {
101 if (NULL != ccc->p[i])
102 {
103 GNUNET_TRANSPORT_TESTING_stop_peer (ccc->p[i]);
104 ccc->p[i] = NULL;
105 }
106 }
107}
108
109
110/**
111 * Testcase hit timeout, shut it down with error.
112 *
113 * @param cls our `struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *`
114 */
115static void
116do_timeout (void *cls)
117{
118 struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = cls;
119
120 ccc->timeout_task = NULL;
121 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
122 "Testcase timed out\n");
123 ccc->global_ret = GNUNET_SYSERR;
124 GNUNET_SCHEDULER_shutdown ();
125}
126
127
128/**
129 * Internal data structure. Closure for
130 * #connect_cb, #disconnect_cb, #my_nc and #start_cb.
131 * Allows us to identify which peer this is about.
132 */
133struct GNUNET_TRANSPORT_TESTING_InternalPeerContext
134{
135 /**
136 * Overall context of the callback.
137 */
138 struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc;
139
140 /**
141 * Offset of the peer this is about.
142 */
143 unsigned int off;
144};
145
146
147/**
148 * Information tracked per connected peer.
149 */
150struct ConnectPairInfo
151{
152 /**
153 * Peer this is about.
154 */
155 const struct GNUNET_PeerIdentity *sender;
156
157 /**
158 * Information about the receiving peer.
159 */
160 struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *ipi;
161};
162
163
164/**
165 * Function called when we connected two peers. Once we have gotten
166 * to the clique, launch test-specific logic.
167 *
168 * @param cls our `struct GNUNET_TRANSPORT_TESTING_ConnectRequestList *`
169 */
170static void
171connect_cb (void *cls)
172{
173 struct GNUNET_TRANSPORT_TESTING_ConnectRequestList *crl = cls;
174 struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = crl->ccc;
175
176 GNUNET_CONTAINER_DLL_remove (ccc->crl_head,
177 ccc->crl_tail,
178 crl);
179 {
180 char *p1_c = GNUNET_strdup (GNUNET_i2s (&crl->p1->id));
181
182 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
183 "Peers connected: %u (%s) <-> %u (%s)\n",
184 crl->p1->no,
185 p1_c,
186 crl->p2->no,
187 GNUNET_i2s (&crl->p2->id));
188 GNUNET_free (p1_c);
189 GNUNET_free (crl);
190 }
191 if (NULL == ccc->crl_head)
192 {
193 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
194 "All connections UP, launching custom test logic.\n");
195 GNUNET_SCHEDULER_add_now (ccc->connect_continuation,
196 ccc->connect_continuation_cls);
197 }
198}
199
200
201/**
202 * Find peer by peer ID.
203 *
204 * @param ccc context to search
205 * @param peer peer to look for
206 * @return NULL if @a peer was not found
207 */
208struct GNUNET_TRANSPORT_TESTING_PeerContext *
209GNUNET_TRANSPORT_TESTING_find_peer (struct
210 GNUNET_TRANSPORT_TESTING_ConnectCheckContext
211 *ccc,
212 const struct GNUNET_PeerIdentity *peer)
213{
214 for (unsigned int i = 0; i < ccc->num_peers; i++)
215 if ((NULL != ccc->p[i]) &&
216 (0 == memcmp (peer,
217 &ccc->p[i]->id,
218 sizeof(*peer))))
219 return ccc->p[i];
220 return NULL;
221}
222
223
224/**
225 * Wrapper around peers connecting. Calls client's nc function.
226 *
227 * @param cls our `struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *`
228 * @param peer peer we got connected to
229 * @param mq message queue for transmissions to @a peer
230 * @return closure for message handlers
231 */
232static void *
233my_nc (void *cls,
234 const struct GNUNET_PeerIdentity *peer,
235 struct GNUNET_MQ_Handle *mq)
236{
237 struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *ipi = cls;
238 struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = ipi->ccc;
239 struct ConnectPairInfo *cpi;
240
241 if (NULL != ccc->nc)
242 ccc->nc (ccc->cls,
243 ccc->p[ipi->off],
244 peer);
245 cpi = GNUNET_new (struct ConnectPairInfo);
246 cpi->ipi = ipi;
247 cpi->sender = peer; /* valid until disconnect */
248 return cpi;
249}
250
251
252/**
253 * Wrapper around peers disconnecting. Calls client's nd function.
254 *
255 * @param cls our `struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *`
256 * @param peer peer we got disconnected from
257 * @param custom_cls return value from @a my_nc
258 */
259static void
260my_nd (void *cls,
261 const struct GNUNET_PeerIdentity *peer,
262 void *custom_cls)
263{
264 struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *ipi = cls;
265 struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = ipi->ccc;
266 struct ConnectPairInfo *cpi = custom_cls;
267
268 if (NULL != ccc->nd)
269 ccc->nd (ccc->cls,
270 ccc->p[ipi->off],
271 peer);
272 GNUNET_free (cpi);
273}
274
275
276/**
277 * Wrapper around receiving data. Calls client's rec function.
278 *
279 * @param cls our `struct ConnectPairInfo *`
280 * @param message message we received
281 * @return #GNUNET_OK (all messages are fine)
282 */
283static int
284check_test (void *cls,
285 const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
286{
287 return GNUNET_OK;
288}
289
290
291/**
292 * Wrapper around receiving data. Calls client's rec function.
293 *
294 * @param cls our `struct ConnectPairInfo *`
295 * @param message message we received
296 */
297static void
298handle_test (void *cls,
299 const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
300{
301 struct ConnectPairInfo *cpi = cls;
302 struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *ipi = cpi->ipi;
303 struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = ipi->ccc;
304
305 if (NULL != ccc->rec)
306 ccc->rec (ccc->cls,
307 ccc->p[ipi->off],
308 cpi->sender,
309 message);
310}
311
312
313/**
314 * Wrapper around receiving data. Calls client's rec function.
315 *
316 * @param cls our `struct ConnectPairInfo *`
317 * @param message message we received
318 * @return #GNUNET_OK (all messages are fine)
319 */
320static int
321check_test2 (void *cls,
322 const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
323{
324 return GNUNET_OK;
325}
326
327
328/**
329 * Wrapper around receiving data. Calls client's rec function.
330 *
331 * @param cls our `struct ConnectPairInfo *`
332 * @param message message we received
333 */
334static void
335handle_test2 (void *cls,
336 const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
337{
338 struct ConnectPairInfo *cpi = cls;
339 struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *ipi = cpi->ipi;
340 struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = ipi->ccc;
341
342 if (NULL != ccc->rec)
343 ccc->rec (ccc->cls,
344 ccc->p[ipi->off],
345 cpi->sender,
346 message);
347}
348
349
350/**
351 * Connect the peers as a clique.
352 *
353 * @param cls our `struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext`
354 */
355static void
356do_connect (void *cls)
357{
358 struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = cls;
359
360 ccc->connect_task = NULL;
361 for (unsigned int i = 0; i < ccc->num_peers; i++)
362 for (unsigned int j = (ccc->bi_directional ? 0 : i + 1); j < ccc->num_peers;
363 j++)
364 {
365 struct GNUNET_TRANSPORT_TESTING_ConnectRequestList *crl;
366
367 if (i == j)
368 continue;
369 crl = GNUNET_new (struct GNUNET_TRANSPORT_TESTING_ConnectRequestList);
370 GNUNET_CONTAINER_DLL_insert (ccc->crl_head,
371 ccc->crl_tail,
372 crl);
373 crl->ccc = ccc;
374 crl->p1 = ccc->p[i];
375 crl->p2 = ccc->p[j];
376 {
377 char *sender_c = GNUNET_strdup (GNUNET_i2s (&ccc->p[0]->id));
378
379 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
380 "Test tries to connect peer %u (`%s') -> peer %u (`%s')\n",
381 ccc->p[0]->no,
382 sender_c,
383 ccc->p[1]->no,
384 GNUNET_i2s (&ccc->p[1]->id));
385 GNUNET_free (sender_c);
386 }
387 crl->cr = GNUNET_TRANSPORT_TESTING_connect_peers (ccc->p[i],
388 ccc->p[j],
389 &connect_cb,
390 crl);
391 }
392}
393
394
395/**
396 * Function called once we have successfully launched a peer.
397 * Once all peers have been launched, we connect all of them
398 * in a clique.
399 *
400 * @param cls our `struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *`
401 */
402static void
403start_cb (void *cls)
404{
405 struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *ipi = cls;
406 struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = ipi->ccc;
407 struct GNUNET_TRANSPORT_TESTING_PeerContext *p = ccc->p[ipi->off];
408
409 ccc->started++;
410 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
411 "Peer %u (`%s') started\n",
412 p->no,
413 GNUNET_i2s (&p->id));
414 if (ccc->started != ccc->num_peers)
415 return;
416 if (NULL != ccc->pre_connect_task)
417 {
418 /* Run the custom per-connect job, then give it a second to
419 go into effect before we continue connecting peers. */
420 ccc->pre_connect_task (ccc->pre_connect_task_cls);
421 ccc->connect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
422 &do_connect,
423 ccc);
424 }
425 else
426 {
427 do_connect (ccc);
428 }
429}
430
431
432/**
433 * Function run from #GNUNET_TRANSPORT_TESTING_connect_check
434 * once the scheduler is up. Should launch the peers and
435 * then in the continuations try to connect them.
436 *
437 * @param cls our `struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *`
438 * @param args ignored
439 * @param cfgfile ignored
440 * @param cfg configuration
441 */
442static void
443connect_check_run (void *cls,
444 char *const *args,
445 const char *cfgfile,
446 const struct GNUNET_CONFIGURATION_Handle *cfg)
447{
448 struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = cls;
449 int ok;
450
451 ccc->cfg = cfg;
452 ccc->timeout_task = GNUNET_SCHEDULER_add_delayed (ccc->timeout,
453 &do_timeout,
454 ccc);
455 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
456 ccc);
457 ok = GNUNET_OK;
458 for (unsigned int i = 0; i < ccc->num_peers; i++)
459 {
460 struct GNUNET_MQ_MessageHandler handlers[] = {
461 GNUNET_MQ_hd_var_size (test,
462 GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE,
463 struct GNUNET_TRANSPORT_TESTING_TestMessage,
464 NULL),
465 GNUNET_MQ_hd_var_size (test2,
466 GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE2,
467 struct GNUNET_TRANSPORT_TESTING_TestMessage,
468 NULL),
469 GNUNET_MQ_handler_end ()
470 };
471 ccc->p[i] = GNUNET_TRANSPORT_TESTING_start_peer (ccc->tth,
472 ccc->cfg_files[i],
473 i + 1,
474 handlers,
475 &my_nc,
476 &my_nd,
477 &ccc->ip[i],
478 &start_cb,
479 &ccc->ip[i]);
480 if (NULL == ccc->p[i])
481 ok = GNUNET_SYSERR;
482 }
483 if (GNUNET_OK != ok)
484 {
485 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
486 "Fail! Could not start peers!\n");
487 GNUNET_SCHEDULER_shutdown ();
488 }
489}
490
491
492/**
493 * Common implementation of the #GNUNET_TRANSPORT_TESTING_CheckCallback.
494 * Starts and connects the two peers, then invokes the
495 * `connect_continuation` from @a cls. Sets up a timeout to
496 * abort the test, and a shutdown handler to clean up properly
497 * on exit.
498 *
499 * @param cls closure of type `struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext`
500 * @param tth_ initialized testing handle
501 * @param test_plugin_ name of the plugin
502 * @param test_name_ name of the test
503 * @param num_peers number of entries in the @a cfg_file array
504 * @param cfg_files array of names of configuration files for the peers
505 * @return #GNUNET_SYSERR on error
506 */
507int
508GNUNET_TRANSPORT_TESTING_connect_check (void *cls,
509 struct GNUNET_TRANSPORT_TESTING_Handle *
510 tth_,
511 const char *test_plugin_,
512 const char *test_name_,
513 unsigned int num_peers,
514 char *cfg_files[])
515{
516 static struct GNUNET_GETOPT_CommandLineOption options[] = {
517 GNUNET_GETOPT_OPTION_END
518 };
519 struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = cls;
520 struct GNUNET_TRANSPORT_TESTING_PeerContext *p[num_peers];
521 struct GNUNET_TRANSPORT_TESTING_InternalPeerContext ip[num_peers];
522 char *argv[] = {
523 (char *) test_name_,
524 "-c",
525 (char *) ccc->config_file,
526 NULL
527 };
528
529 ccc->num_peers = num_peers;
530 ccc->cfg_files = cfg_files;
531 ccc->test_plugin = test_plugin_;
532 ccc->test_name = test_name_;
533 ccc->tth = tth_;
534 ccc->global_ret = GNUNET_OK;
535 ccc->p = p;
536 ccc->ip = ip;
537 for (unsigned int i = 0; i < num_peers; i++)
538 {
539 ip[i].off = i;
540 ip[i].ccc = ccc;
541 }
542 if (GNUNET_OK !=
543 GNUNET_PROGRAM_run ((sizeof(argv) / sizeof(char *)) - 1,
544 argv,
545 test_name_,
546 "nohelp",
547 options,
548 &connect_check_run,
549 ccc))
550 return GNUNET_SYSERR;
551 return ccc->global_ret;
552}
553
554
555/**
556 * Setup testcase. Calls @a check with the data the test needs.
557 *
558 * @param argv0 binary name (argv[0])
559 * @param filename source file name (__FILE__)
560 * @param num_peers number of peers to start
561 * @param check main function to run
562 * @param check_cls closure for @a check
563 * @return #GNUNET_OK on success
564 */
565int
566GNUNET_TRANSPORT_TESTING_main_ (const char *argv0,
567 const char *filename,
568 unsigned int num_peers,
569 GNUNET_TRANSPORT_TESTING_CheckCallback check,
570 void *check_cls)
571{
572 struct GNUNET_TRANSPORT_TESTING_Handle *tth;
573 char *test_name;
574 char *test_source;
575 char *test_plugin;
576 char *cfg_names[num_peers];
577 int ret;
578
579 ret = GNUNET_OK;
580 test_name = GNUNET_TRANSPORT_TESTING_get_test_name (argv0);
581 GNUNET_log_setup (test_name,
582 "WARNING",
583 NULL);
584 test_source = GNUNET_TRANSPORT_TESTING_get_test_source_name (filename);
585 test_plugin = GNUNET_TRANSPORT_TESTING_get_test_plugin_name (argv0,
586 test_source);
587 for (unsigned int i = 0; i < num_peers; i++)
588 cfg_names[i] = GNUNET_TRANSPORT_TESTING_get_config_name (argv0,
589 i + 1);
590 tth = GNUNET_TRANSPORT_TESTING_init ();
591 if (NULL == tth)
592 {
593 ret = GNUNET_SYSERR;
594 }
595 else
596 {
597 ret = check (check_cls,
598 tth,
599 test_plugin,
600 test_name,
601 num_peers,
602 cfg_names);
603 GNUNET_TRANSPORT_TESTING_done (tth);
604 }
605 for (unsigned int i = 0; i < num_peers; i++)
606 GNUNET_free (cfg_names[i]);
607 GNUNET_free (test_source);
608 GNUNET_free (test_plugin);
609 GNUNET_free (test_name);
610 return ret;
611}
612
613
614/* end of transport-testing-main.c */