call GNUNET_SERVER_receive_done() also on internal error paths
[oweals/gnunet.git] / src / transport / test_transport_address_switch.c
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2009, 2010, 2011 Christian Grothoff (and other contributing authors)
4
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.
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  General Public License for more details.
14
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., 59 Temple Place - Suite 330,
18  Boston, MA 02111-1307, USA.
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
37  * outside, the test still passes when no address switching attempt takes
38  * place. It fails if an address switch attempt fails.
39  */
40 #include "platform.h"
41 #include "gnunet_transport_service.h"
42 #include "gnunet_ats_service.h"
43 #include "gauger.h"
44 #include "transport-testing.h"
45
46 /*
47  * Testcase specific declarations
48  */
49
50 GNUNET_NETWORK_STRUCT_BEGIN
51 struct TestMessage
52 {
53   struct GNUNET_MessageHeader header;
54   uint32_t num GNUNET_PACKED;
55 };
56 GNUNET_NETWORK_STRUCT_END
57
58 /**
59  * Message type for test messages
60  */
61 #define MTYPE 12345
62
63 /**
64  * Message size for test messages
65  */
66 #define MSIZE 2048
67
68 /**
69  * Testcase timeout
70  */
71 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120)
72
73 /**
74  * How long until we give up on transmitting the message?
75  */
76 #define TIMEOUT_TRANSMIT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60)
77
78 #define DURATION GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
79
80
81 /**
82  * Timeout task to send messages
83  */
84 static struct GNUNET_SCHEDULER_Task *die_task;
85
86
87 static struct GNUNET_SCHEDULER_Task *delayed_end_task;
88
89 /**
90  * Measurement task to send messages
91  */
92 static struct GNUNET_SCHEDULER_Task *measure_task;
93
94
95 static struct PeerContext *p1;
96 static char *cfg_file_p1;
97 static struct GNUNET_STATISTICS_Handle *p1_stat;
98
99 static struct PeerContext *p2;
100 static char *cfg_file_p2;
101 static struct GNUNET_STATISTICS_Handle *p2_stat;
102
103 static struct PeerContext *sender;
104
105 static struct PeerContext *receiver;
106
107 static struct GNUNET_TRANSPORT_TransmitHandle *th;
108
109 static struct GNUNET_TRANSPORT_TESTING_handle *tth;
110
111 static GNUNET_TRANSPORT_TESTING_ConnectRequest cc;
112
113 static int test_connected;
114
115 static int res;
116
117
118 /**
119  * Statistics about peer 1
120  */
121 static unsigned int p1_addresses_avail;
122 static unsigned int p1_switch_attempts;
123 static unsigned int p1_switch_success;
124 static unsigned int p1_switch_fail;
125
126
127 /**
128  * Statistics about peer 2
129  */
130 static unsigned int p2_switch_attempts;
131 static unsigned int p2_switch_success;
132 static unsigned int p2_switch_fail;
133 static unsigned int p2_addresses_avail;
134
135 /**
136  * Transmission statistics
137  */
138
139 /* Amount of data transfered since last switch attempt */
140 static unsigned long long bytes_sent_after_switch;
141 static unsigned long long bytes_recv_after_switch;
142
143
144 #if VERBOSE
145 #define OKPP do { ok++; FPRINTF (stderr, "Now at stage %u at %s:%u\n", ok, __FILE__, __LINE__); } while (0)
146 #else
147 #define OKPP do { ok++; } while (0)
148 #endif
149
150
151 static int
152 stat_start_attempt_cb (void *cls,
153                        const char *subsystem,
154                        const char *name,
155                        uint64_t value,
156                        int is_persistent)
157 {
158   if (cls == p1)
159   {
160     p1_switch_attempts++;
161     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "(1:s)");
162   }
163   else if (cls == p2)
164   {
165     p2_switch_attempts++;
166     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "(2:s)");
167   }
168
169   bytes_recv_after_switch = 0;
170   bytes_sent_after_switch = 0;
171
172   return GNUNET_OK;
173 }
174
175
176 static int
177 stat_success_attempt_cb (void *cls,
178                          const char *subsystem,
179                          const char *name,
180                          uint64_t value,
181                          int is_persistent)
182 {
183   if (cls == p1)
184   {
185     p1_switch_success++;
186     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "(1:+)");
187   }
188   if (cls == p2)
189   {
190     p2_switch_success++;
191     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "(2:+)");
192   }
193
194   return GNUNET_OK;
195 }
196
197
198 static int
199 stat_fail_attempt_cb (void *cls,
200                       const char *subsystem,
201                       const char *name,
202                       uint64_t value,
203                       int is_persistent)
204 {
205   if (value == 0)
206     return GNUNET_OK;
207
208   if (cls == p1)
209   {
210     p1_switch_fail++;
211     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "(1:-)");
212   }
213   if (cls == p2)
214   {
215     p2_switch_fail++;
216     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "(2:-)");
217   }
218
219   return GNUNET_OK;
220 }
221
222
223 static int
224 stat_addresses_available (void *cls,
225                           const char *subsystem,
226                           const char *name,
227                           uint64_t value,
228                           int is_persistent)
229 {
230   if (cls == p1)
231   {
232     p1_addresses_avail++;
233   }
234   if (cls == p2)
235   {
236     p2_addresses_avail++;
237   }
238   return GNUNET_OK;
239 }
240
241
242 static void
243 clean_up ()
244 {
245   if (measure_task != NULL)
246   {
247     GNUNET_SCHEDULER_cancel (measure_task);
248     measure_task = NULL;
249   }
250
251   if (delayed_end_task != NULL)
252   {
253     GNUNET_SCHEDULER_cancel (delayed_end_task);
254     delayed_end_task = NULL;
255   }
256
257   if (die_task != NULL)
258   {
259     GNUNET_SCHEDULER_cancel (die_task);
260     die_task = NULL;
261   }
262
263   if (NULL != p1_stat)
264   {
265     GNUNET_STATISTICS_watch_cancel (p1_stat, "transport",
266         "# Attempts to switch addresses",
267         stat_start_attempt_cb, p1);
268     GNUNET_STATISTICS_watch_cancel (p1_stat, "transport",
269         "# Successful attempts to switch addresses",
270         stat_success_attempt_cb, p1);
271     GNUNET_STATISTICS_watch_cancel (p1_stat, "transport",
272         "# Failed attempts to switch addresses (failed to send CONNECT CONT)",
273         stat_fail_attempt_cb, p1);
274     GNUNET_STATISTICS_watch_cancel (p1_stat, "transport",
275         "# Failed attempts to switch addresses (failed to send CONNECT)",
276         stat_fail_attempt_cb, p1);
277     GNUNET_STATISTICS_watch_cancel (p1_stat, "transport",
278         "# Failed attempts to switch addresses (no response)",
279         stat_fail_attempt_cb, p1);
280     GNUNET_STATISTICS_watch (p1_stat, "transport",
281         "# transport addresses",
282         stat_addresses_available, p1);
283     GNUNET_STATISTICS_destroy (p1_stat, GNUNET_NO);
284     p1_stat = NULL;
285   }
286   if (NULL != p2_stat)
287   {
288     GNUNET_STATISTICS_watch_cancel (p2_stat, "transport",
289         "# Attempts to switch addresses", stat_start_attempt_cb, p2);
290     GNUNET_STATISTICS_watch_cancel (p2_stat, "transport",
291         "# Successful attempts to switch addresses", stat_success_attempt_cb, p2);
292     GNUNET_STATISTICS_watch_cancel (p2_stat, "transport",
293         "# Failed attempts to switch addresses (failed to send CONNECT CONT)",
294         stat_fail_attempt_cb, p2);
295     GNUNET_STATISTICS_watch_cancel (p2_stat, "transport",
296         "# Failed attempts to switch addresses (failed to send CONNECT)",
297         stat_fail_attempt_cb, p2);
298     GNUNET_STATISTICS_watch_cancel (p2_stat, "transport",
299         "# Failed attempts to switch addresses (no response)",
300         stat_fail_attempt_cb, p2);
301     GNUNET_STATISTICS_watch (p2_stat, "transport",
302         "# transport addresses",
303         stat_addresses_available, p2);
304     GNUNET_STATISTICS_destroy (p2_stat, GNUNET_NO);
305     p2_stat = NULL;
306   }
307
308   if (th != NULL)
309   {
310     GNUNET_TRANSPORT_notify_transmit_ready_cancel (th);
311     th = NULL;
312   }
313   if (cc != NULL)
314   {
315     GNUNET_TRANSPORT_TESTING_connect_peers_cancel (tth, cc);
316     cc = NULL;
317   }
318   if (p1 != NULL)
319   {
320     GNUNET_TRANSPORT_TESTING_stop_peer (tth, p1);
321     p1 = NULL;
322   }
323   if (p2 != NULL)
324   {
325     GNUNET_TRANSPORT_TESTING_stop_peer (tth, p2);
326     p2 = NULL;
327   }
328 }
329
330
331 static void
332 end ()
333 {
334   int result = 0;
335
336   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
337               "Stopping peers\n");
338
339   delayed_end_task = NULL;
340   FPRINTF (stderr, "\n");
341   if (p1_switch_attempts > 0)
342   {
343     FPRINTF (stderr,
344              "Peer 1 tried %u times to switch and succeeded %u times, failed %u times\n",
345              p1_switch_attempts,
346              p1_switch_success,
347              p1_switch_fail);
348     if (p1_switch_success != p1_switch_attempts)
349     {
350       GNUNET_break (0);
351       result ++;
352     }
353   }
354   else if (p1_addresses_avail > 1)
355   {
356     FPRINTF (stderr,
357              "Peer 1 had %u addresses available, but did not try to switch\n",
358              p1_addresses_avail);
359   }
360   if (p2_switch_attempts > 0)
361   {
362     FPRINTF (stderr,
363              "Peer 2 tried %u times to switch and succeeded %u times, failed %u times\n",
364              p2_switch_attempts,
365              p2_switch_success,
366              p2_switch_fail);
367     if (p2_switch_success != p2_switch_attempts)
368     {
369       GNUNET_break (0);
370       result++;
371     }
372   }
373   else if (p2_addresses_avail > 1)
374   {
375     FPRINTF (stderr,
376              "Peer 2 had %u addresses available, but did not try to switch\n",
377              p2_addresses_avail);
378   }
379
380   if ( ((p1_switch_attempts > 0) || (p2_switch_attempts > 0)) &&
381        (bytes_sent_after_switch == 0) )
382   {
383     FPRINTF (stderr, "No data sent after switching!\n");
384     GNUNET_break (0);
385     res++;
386   }
387   if ( ((p1_switch_attempts > 0) || (p2_switch_attempts > 0)) &&
388        (bytes_recv_after_switch == 0) )
389   {
390     FPRINTF (stderr, "No data received after switching!\n");
391     GNUNET_break (0);
392     res++;
393   }
394
395   clean_up();
396
397   res = result;
398 }
399
400
401 static void
402 end_badly ()
403 {
404   die_task = NULL;
405   clean_up();
406   if (0 == p1_switch_attempts + p2_switch_attempts)
407   {
408     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
409                 "Test did not work, as peers didn't switch (flawed testcase)!\n");
410     res = 0;
411   }
412   else
413   {
414     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
415               "Fail (timeout)! No transmission after switch! Stopping peers\n");
416     res = GNUNET_YES;
417   }
418   if (test_connected == GNUNET_YES)
419     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
420                 "Peers got connected\n");
421   else
422     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
423                 "Peers got NOT EVEN connected\n");
424 }
425
426
427 static void
428 notify_receive (void *cls,
429                 const struct GNUNET_PeerIdentity *peer,
430                 const struct GNUNET_MessageHeader *message)
431 {
432   const struct TestMessage *hdr;
433
434   hdr = (const struct TestMessage *) message;
435   if (MTYPE != ntohs (message->type))
436     return;
437
438   struct PeerContext *p = cls;
439   char *ps = GNUNET_strdup (GNUNET_i2s (&p->id));
440
441   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
442               "Peer %u (`%s') got message %u of size %u from peer (`%s')\n", p->no, ps,
443               ntohl (hdr->num),
444               ntohs (message->size),
445               GNUNET_i2s (peer));
446   if ( ((p1_switch_attempts >= 1) || (p2_switch_attempts >= 1)) &&
447         (p1_switch_attempts == p1_switch_fail + p1_switch_success) &&
448         (p2_switch_attempts == p2_switch_fail + p2_switch_success) )
449   {
450     bytes_recv_after_switch += ntohs(hdr->header.size);
451     if ((bytes_sent_after_switch > 0) && (bytes_recv_after_switch > 0))
452     {
453       /* A peer switched addresses and sent and received data after the
454        * switch operations */
455       end ();
456     }
457   }
458
459   GNUNET_free(ps);
460 }
461
462
463 static size_t
464 notify_ready (void *cls, size_t size, void *buf)
465 {
466   static uint32_t counter;
467   char *cbuf = buf;
468   struct TestMessage hdr;
469
470   th = NULL;
471   if (buf == NULL)
472   {
473     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
474                "Timeout occurred while waiting for transmit_ready for message\n");
475     if (NULL != die_task)
476       GNUNET_SCHEDULER_cancel (die_task);
477     die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL);
478     res = 1;
479     return 0;
480   }
481
482   GNUNET_assert(size >= MSIZE);
483   GNUNET_assert(buf != NULL);
484   cbuf = buf;
485
486   hdr.header.size = htons (MSIZE);
487   hdr.header.type = htons (MTYPE);
488   hdr.num = htonl (counter++);
489   memcpy (&cbuf[0], &hdr, sizeof(struct TestMessage));
490   memset (&cbuf[sizeof(struct TestMessage)], '0', MSIZE - sizeof(struct TestMessage));
491
492   char *receiver_s = GNUNET_strdup (GNUNET_i2s (&receiver->id));
493   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
494               "Sending message %u of size %u from peer %u (`%4s') -> peer %u (`%s') !\n",
495               (unsigned int) (counter - 1),
496               MSIZE,
497               sender->no,
498               GNUNET_i2s (&sender->id),
499               receiver->no,
500               receiver_s);
501   GNUNET_free(receiver_s);
502
503   if (th == NULL)
504     th = GNUNET_TRANSPORT_notify_transmit_ready (p2->th,
505                                                  &p1->id,
506                                                  MSIZE,
507                                                  TIMEOUT_TRANSMIT,
508                                                  &notify_ready, NULL);
509
510   if ( ((p1_switch_attempts >= 1) || (p2_switch_attempts >= 1)) &&
511         (p1_switch_attempts == p1_switch_fail + p1_switch_success) &&
512         (p2_switch_attempts == p2_switch_fail + p2_switch_success) )
513   {
514     bytes_sent_after_switch += MSIZE;
515   }
516   return MSIZE;
517 }
518
519
520 static void
521 notify_connect (void *cls,
522                 const struct GNUNET_PeerIdentity *peer)
523 {
524   struct PeerContext *p = cls;
525
526   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
527               "Peer %u (`%4s') connected to us!\n",
528               p->no,
529               GNUNET_i2s (peer));
530 }
531
532
533 static void
534 notify_disconnect (void *cls,
535                    const struct GNUNET_PeerIdentity *peer)
536 {
537   struct PeerContext *p = cls;
538
539   if (NULL != p1)
540   {
541     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
542                 "Peer %u (`%4s') disconnected early!\n",
543                 p->no,
544                 GNUNET_i2s (peer));
545     GNUNET_SCHEDULER_shutdown ();
546   }
547   if (NULL != th)
548   {
549     GNUNET_TRANSPORT_notify_transmit_ready_cancel (th);
550     th = NULL;
551   }
552 }
553
554
555 static void
556 sendtask ()
557 {
558   /* Transmit test messages */
559   th = GNUNET_TRANSPORT_notify_transmit_ready (p2->th,
560                                                &p1->id, MSIZE,
561                                                TIMEOUT_TRANSMIT,
562                                                &notify_ready, NULL);
563 }
564
565
566 static void
567 progress_indicator (void *cls,
568                     const struct GNUNET_SCHEDULER_TaskContext *tc)
569 {
570   static int counter;
571
572   measure_task = NULL;
573   counter++;
574   if ((DURATION.rel_value_us / 1000 / 1000LL) < counter)
575   {
576     FPRINTF (stderr, "%s", ".\n");
577   }
578   else
579   {
580     FPRINTF (stderr, "%s", ".");
581     measure_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
582                                                  &progress_indicator, NULL);
583   }
584 }
585
586
587 static void
588 testing_connect_cb (struct PeerContext *p1,
589                     struct PeerContext *p2,
590                     void *cls)
591 {
592   char *p1_c = GNUNET_strdup (GNUNET_i2s (&p1->id));
593
594   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
595               "Peers connected: %u (%s) <-> %u (%s)\n",
596               p1->no, p1_c, p2->no,
597               GNUNET_i2s (&p2->id));
598   GNUNET_free (p1_c);
599
600   cc = NULL;
601   test_connected = GNUNET_YES;
602
603   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
604               "(i:s/+/-) \t i == peer 1/2, s/+/- : switch attempt/switch ok/switch fail\n");
605
606   /* Show progress */
607   measure_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
608                                                &progress_indicator,
609                                                NULL);
610   /* Peers are connected, start transmit test messages */
611   GNUNET_SCHEDULER_add_now (&sendtask, NULL);
612 }
613
614
615 static void
616 start_cb (struct PeerContext *p, void *cls)
617 {
618   static int started;
619   started++;
620
621   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
622               "Peer %u (`%s') started\n",
623               p->no,
624               GNUNET_i2s (&p->id));
625   if (started != 2)
626     return;
627
628   test_connected = GNUNET_NO;
629   sender = p2;
630   receiver = p1;
631
632   char *sender_c = GNUNET_strdup (GNUNET_i2s (&sender->id));
633   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
634               "Test tries to send from %u (%s) -> peer %u (%s)\n",
635               sender->no,
636               sender_c,
637               receiver->no,
638               GNUNET_i2s (&receiver->id));
639   GNUNET_free (sender_c);
640
641   /* Connect the peers */
642   cc = GNUNET_TRANSPORT_TESTING_connect_peers (tth, p1, p2,
643                                                &testing_connect_cb,
644                                                NULL);
645 }
646
647
648 static void
649 run (void *cls,
650      char * const *args,
651      const char *cfgfile,
652      const struct GNUNET_CONFIGURATION_Handle *cfg)
653 {
654   die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
655
656   p1 = GNUNET_TRANSPORT_TESTING_start_peer (tth, cfg_file_p1, 1,
657       &notify_receive, &notify_connect, &notify_disconnect, &start_cb, NULL);
658
659   p2 = GNUNET_TRANSPORT_TESTING_start_peer (tth, cfg_file_p2, 2,
660       &notify_receive, &notify_connect, &notify_disconnect, &start_cb, NULL);
661
662   if ((p1 == NULL )|| (p2 == NULL))
663   {
664     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Fail! Could not start peers!\n");
665     GNUNET_SCHEDULER_shutdown ();
666     return;
667   }
668
669   /* Start to watch statistics for peer 1 */
670   p1_stat = GNUNET_STATISTICS_create ("transport", p1->cfg);
671   GNUNET_STATISTICS_watch (p1_stat, "transport",
672       "# Attempts to switch addresses",
673       stat_start_attempt_cb, p1);
674   GNUNET_STATISTICS_watch (p1_stat, "transport",
675       "# Successful attempts to switch addresses",
676       stat_success_attempt_cb, p1);
677   GNUNET_STATISTICS_watch (p1_stat, "transport",
678       "# Failed attempts to switch addresses (failed to send CONNECT CONT)",
679       stat_fail_attempt_cb, p1);
680   GNUNET_STATISTICS_watch (p1_stat, "transport",
681       "# Failed attempts to switch addresses (failed to send CONNECT)",
682       stat_fail_attempt_cb, p1);
683   GNUNET_STATISTICS_watch (p1_stat, "transport",
684       "# Failed attempts to switch addresses (no response)",
685       stat_fail_attempt_cb, p1);
686   GNUNET_STATISTICS_watch (p1_stat, "transport",
687       "# transport addresses",
688       stat_addresses_available, p1);
689
690   /* Start to watch statistics for peer 2  */
691   p2_stat = GNUNET_STATISTICS_create ("transport", p2->cfg);
692   GNUNET_STATISTICS_watch (p2_stat, "transport",
693       "# Attempts to switch addresses",
694       stat_start_attempt_cb, p2);
695   GNUNET_STATISTICS_watch (p2_stat, "transport",
696       "# Successful attempts to switch addresses",
697       stat_success_attempt_cb, p2);
698   GNUNET_STATISTICS_watch (p2_stat, "transport",
699       "# Failed attempts to switch addresses (failed to send CONNECT CONT)",
700       stat_fail_attempt_cb, p2);
701   GNUNET_STATISTICS_watch (p2_stat, "transport",
702       "# Failed attempts to switch addresses (failed to send CONNECT)",
703       stat_fail_attempt_cb, p2);
704   GNUNET_STATISTICS_watch (p2_stat, "transport",
705       "# Failed attempts to switch addresses (no response)",
706       stat_fail_attempt_cb, p2);
707   GNUNET_STATISTICS_watch (p2_stat, "transport",
708       "# transport addresses",
709       stat_addresses_available, p2);
710
711   if ((p1_stat == NULL )|| (p2_stat == NULL))
712   {
713     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
714                 "Fail! Could not create statistics for peers!\n");
715     GNUNET_SCHEDULER_shutdown ();
716     return;
717   }
718 }
719
720 int
721 main (int argc, char *argv[])
722 {
723   char *test_plugin;
724   char *test_source;
725   char *test_name;
726
727   static char *argv_new[] = { "test-transport-address-switch", "-c",
728       "test_transport_startonly.conf", NULL };
729
730   static struct GNUNET_GETOPT_CommandLineOption options[] = {
731       GNUNET_GETOPT_OPTION_END };
732
733   GNUNET_TRANSPORT_TESTING_get_test_name (argv[0], &test_name);
734
735   GNUNET_log_setup (test_name, "WARNING", NULL );
736
737   GNUNET_TRANSPORT_TESTING_get_test_source_name (__FILE__, &test_source);
738   GNUNET_TRANSPORT_TESTING_get_test_plugin_name (argv[0], test_source,
739       &test_plugin);
740
741   tth = GNUNET_TRANSPORT_TESTING_init ();
742
743   GNUNET_TRANSPORT_TESTING_get_config_name (argv[0], &cfg_file_p1, 1);
744   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Using cfg [%u] : %s \n", 1, cfg_file_p1);
745   GNUNET_TRANSPORT_TESTING_get_config_name (argv[0], &cfg_file_p2, 2);
746   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Using cfg [%u] : %s \n", 2, cfg_file_p2);
747
748   GNUNET_PROGRAM_run ((sizeof(argv_new) / sizeof(char *)) - 1, argv_new,
749       test_name, "nohelp", options, &run, NULL );
750
751   GNUNET_free(cfg_file_p1);
752   GNUNET_free(cfg_file_p2);
753
754   GNUNET_free(test_source);
755   GNUNET_free(test_plugin);
756   GNUNET_free(test_name);
757
758   GNUNET_TRANSPORT_TESTING_done (tth);
759
760   return res;
761 }
762
763 /* end of test_transport_address_switch.c */