more transport testing hacking
[oweals/gnunet.git] / src / transport / test_transport_api.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2009, 2010, 2016 GNUnet e.V.
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., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
19 */
20 /**
21  * @file transport/test_transport_api.c
22  * @brief base test case for transport implementations
23  * @author Christian Grothoff
24  *
25  * This test case serves as a base for tcp, udp, and udp-nat
26  * transport test cases.  Based on the executable being run
27  * the correct test case will be performed.  Conservation of
28  * C code apparently.
29  */
30 #include "platform.h"
31 #include "gnunet_transport_service.h"
32 #include "transport-testing.h"
33
34 /**
35  * How long until we give up on transmitting the message?
36  */
37 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
38
39 /**
40  * How long until we give up on transmitting the message?
41  */
42 #define TIMEOUT_TRANSMIT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
43
44 #define TEST_MESSAGE_SIZE 2600
45
46 #define TEST_MESSAGE_TYPE 12345
47
48
49 static struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc;
50
51 static struct GNUNET_TRANSPORT_TransmitHandle *th;
52
53
54 static void
55 custom_shutdown (void *cls)
56 {
57   if (NULL != th)
58   {
59     GNUNET_TRANSPORT_notify_transmit_ready_cancel (th);
60     th = NULL;
61   }
62 }
63
64
65 static void
66 notify_receive (void *cls,
67                 struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver,
68                 const struct GNUNET_PeerIdentity *sender,
69                 const struct GNUNET_MessageHeader *message)
70 {
71   {
72     char *ps = GNUNET_strdup (GNUNET_i2s (&receiver->id));
73
74     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
75                 "Peer %u (`%s') received message of type %d and size %u size from peer %s!\n",
76                 receiver->no,
77                 ps,
78                 ntohs (message->type),
79                 ntohs (message->size),
80                 GNUNET_i2s (sender));
81     GNUNET_free (ps);
82   }
83
84   if ((TEST_MESSAGE_TYPE == ntohs (message->type)) &&
85       (TEST_MESSAGE_SIZE == ntohs (message->size)))
86   {
87     ccc->global_ret = GNUNET_OK;
88     GNUNET_SCHEDULER_shutdown ();
89   }
90   else
91   {
92     GNUNET_break (0);
93     ccc->global_ret = GNUNET_SYSERR;
94     GNUNET_SCHEDULER_shutdown ();
95   }
96 }
97
98
99 static size_t
100 notify_ready (void *cls,
101               size_t size,
102               void *buf)
103 {
104   struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls;
105   struct GNUNET_MessageHeader *hdr;
106
107   th = NULL;
108   if (buf == NULL)
109   {
110     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
111                 "Timeout occurred while waiting for transmit_ready\n");
112     GNUNET_SCHEDULER_shutdown ();
113     ccc->global_ret = 42;
114     return 0;
115   }
116
117   GNUNET_assert (size >= TEST_MESSAGE_SIZE);
118   if (NULL != buf)
119   {
120     memset (buf, '\0', TEST_MESSAGE_SIZE);
121     hdr = buf;
122     hdr->size = htons (TEST_MESSAGE_SIZE);
123     hdr->type = htons (TEST_MESSAGE_TYPE);
124   }
125
126   {
127     char *ps = GNUNET_strdup (GNUNET_i2s (&ccc->p[1]->id));
128     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
129                 "Peer %u (`%4s') sending message with type %u and size %u bytes to peer %u (`%4s')\n",
130                 ccc->p[1]->no,
131                 ps,
132                 ntohs (hdr->type),
133                 ntohs (hdr->size),
134                 p->no,
135                 GNUNET_i2s (&p->id));
136     GNUNET_free (ps);
137   }
138   return TEST_MESSAGE_SIZE;
139 }
140
141
142 static void
143 sendtask (void *cls)
144 {
145   {
146     char *receiver_s = GNUNET_strdup (GNUNET_i2s (&ccc->p[0]->id));
147
148     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
149                 "Sending message from peer %u (`%s') -> peer %u (`%s') !\n",
150                 ccc->p[1]->no,
151                 GNUNET_i2s (&ccc->p[1]->id),
152                 ccc->p[0]->no,
153                 receiver_s);
154     GNUNET_free (receiver_s);
155   }
156   ccc->global_ret = GNUNET_SYSERR;
157   th = GNUNET_TRANSPORT_notify_transmit_ready (ccc->p[1]->th,
158                                                &ccc->p[0]->id,
159                                                TEST_MESSAGE_SIZE,
160                                                TIMEOUT_TRANSMIT,
161                                                &notify_ready,
162                                                ccc->p[0]);
163   GNUNET_assert (NULL != th);
164 }
165
166
167 static void
168 notify_disconnect (void *cls,
169                    struct GNUNET_TRANSPORT_TESTING_PeerContext *me,
170                    const struct GNUNET_PeerIdentity *other)
171 {
172   GNUNET_TRANSPORT_TESTING_log_disconnect (cls,
173                                            me,
174                                            other);
175   if (NULL != th)
176   {
177     GNUNET_TRANSPORT_notify_transmit_ready_cancel (th);
178     th = NULL;
179   }
180 }
181
182
183 /**
184  * Runs the test.
185  *
186  * @param argv the argv argument from main()
187  * @param bi_directional should we try to establish connections
188  *        in both directions simultaneously?
189  */
190 static int
191 test (char *argv[],
192       int bi_directional)
193 {
194   struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext my_ccc = {
195     .connect_continuation = &sendtask,
196     .config_file = "test_transport_api_data.conf",
197     .rec = &notify_receive,
198     .nc = &GNUNET_TRANSPORT_TESTING_log_connect,
199     .nd = &notify_disconnect,
200     .shutdown_task = &custom_shutdown,
201     .timeout = TIMEOUT,
202     .bi_directional = bi_directional
203   };
204
205   ccc = &my_ccc;
206   if (GNUNET_OK !=
207       GNUNET_TRANSPORT_TESTING_main (2,
208                                      &GNUNET_TRANSPORT_TESTING_connect_check,
209                                      ccc))
210     return 1;
211   return 0;
212 }
213
214
215 int
216 main (int argc,
217       char *argv[])
218 {
219   if ( (0 != test (argv,
220                    GNUNET_NO)) ||
221        (0 != test (argv,
222                    GNUNET_YES) ) )
223     return 1;
224   return 0;
225 }
226
227 /* end of test_transport_api.c */