-Merge branch 'master' of ssh://gnunet.org/gnunet into gsoc2018/rest_api
[oweals/gnunet.git] / src / transport / test_transport_api_monitor_peers.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 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 /**
19  * @file transport/test_transport_api_monitor_peers.c
20  * @brief base test case for transport peer monitor API
21  */
22 #include "platform.h"
23 #include "gnunet_transport_service.h"
24 #include "transport-testing.h"
25
26 /**
27  * How long until we give up on transmitting the message?
28  */
29 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120)
30
31 /**
32  * How long until we give up on transmitting the message?
33  */
34 #define TIMEOUT_TRANSMIT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
35
36 #define TEST_MESSAGE_SIZE 2600
37
38 #define TEST_MESSAGE_TYPE 12345
39
40 static struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc;
41
42 static struct GNUNET_TRANSPORT_PeerMonitoringContext *pmc_p1;
43
44 static struct GNUNET_TRANSPORT_PeerMonitoringContext *pmc_p2;
45
46 static int p1_c;
47
48 static int p2_c;
49
50 static int p1_c_notify;
51
52 static int p2_c_notify;
53
54
55 static void
56 custom_shutdown (void *cls)
57 {
58   if (NULL != pmc_p1)
59   {
60     GNUNET_TRANSPORT_monitor_peers_cancel (pmc_p1);
61     pmc_p1 = NULL;
62   }
63   if (NULL != pmc_p2)
64   {
65     GNUNET_TRANSPORT_monitor_peers_cancel (pmc_p2);
66     pmc_p2 = NULL;
67   }
68 }
69
70
71 static void
72 notify_receive (void *cls,
73                 struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver,
74                 const struct GNUNET_PeerIdentity *sender,
75                 const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
76 {
77   char *ps = GNUNET_strdup (GNUNET_i2s (&receiver->id));
78
79   GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
80               "Peer %u (`%s') received message of type %d and size %u size from peer %s!\n",
81               receiver->no,
82               ps,
83               ntohs (message->header.type),
84               ntohs (message->header.size),
85               GNUNET_i2s (sender));
86   GNUNET_free (ps);
87 }
88
89
90 static void
91 sendtask (void *cls)
92 {
93   /* intentionally empty */
94 }
95
96
97 static void
98 check_done ()
99 {
100   if ( (GNUNET_YES == p1_c) &&
101        (GNUNET_YES == p2_c) &&
102        p1_c_notify &&
103        p2_c_notify)
104   {
105     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
106                 "Both peers state to be connected\n");
107     ccc->global_ret = GNUNET_OK;
108     GNUNET_SCHEDULER_shutdown ();
109   }
110 }
111
112
113 static void
114 notify_connect (void *cls,
115                 struct GNUNET_TRANSPORT_TESTING_PeerContext *me,
116                 const struct GNUNET_PeerIdentity *other)
117 {
118   GNUNET_TRANSPORT_TESTING_log_connect (cls,
119                                         me,
120                                         other);
121   if (0 == memcmp (other, &ccc->p[0]->id, sizeof (struct GNUNET_PeerIdentity)))
122   {
123     p1_c_notify = GNUNET_YES;
124   }
125   if (0 == memcmp (other, &ccc->p[1]->id, sizeof (struct GNUNET_PeerIdentity)))
126   {
127     p2_c_notify = GNUNET_YES;
128   }
129   check_done ();
130 }
131
132
133 static void
134 monitor1_cb (void *cls,
135              const struct GNUNET_PeerIdentity *peer,
136              const struct GNUNET_HELLO_Address *address,
137              enum GNUNET_TRANSPORT_PeerState state,
138              struct GNUNET_TIME_Absolute state_timeout)
139 {
140   if ((NULL == address) || (NULL == ccc->p[0]))
141     return;
142
143   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
144               "Monitor 1: %s %s %s\n",
145               GNUNET_i2s (&address->peer),
146               GNUNET_TRANSPORT_ps2s (state),
147               GNUNET_STRINGS_absolute_time_to_string(state_timeout));
148   if ( (0 == memcmp (&address->peer, &ccc->p[1]->id, sizeof (ccc->p[1]->id))) &&
149        (GNUNET_YES == GNUNET_TRANSPORT_is_connected(state)) &&
150        (GNUNET_NO == p1_c) )
151   {
152     p1_c = GNUNET_YES;
153     check_done ();
154   }
155 }
156
157
158 static void
159 monitor2_cb (void *cls,
160              const struct GNUNET_PeerIdentity *peer,
161              const struct GNUNET_HELLO_Address *address,
162              enum GNUNET_TRANSPORT_PeerState state,
163              struct GNUNET_TIME_Absolute state_timeout)
164 {
165   if ((NULL == address) || (NULL == ccc->p[1]))
166     return;
167
168   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
169               "Monitor 2: %s %s %s\n",
170               GNUNET_i2s (&address->peer),
171               GNUNET_TRANSPORT_ps2s (state),
172               GNUNET_STRINGS_absolute_time_to_string(state_timeout));
173   if ( (0 == memcmp (&address->peer, &ccc->p[0]->id, sizeof (ccc->p[0]->id))) &&
174        (GNUNET_YES == GNUNET_TRANSPORT_is_connected(state)) &&
175        (GNUNET_NO == p2_c) )
176   {
177     p2_c = GNUNET_YES;
178     check_done ();
179   }
180 }
181
182
183 static void
184 start_monitors (void *cls)
185 {
186   pmc_p1 = GNUNET_TRANSPORT_monitor_peers (ccc->p[0]->cfg,
187                                            NULL,
188                                            GNUNET_NO,
189                                            &monitor1_cb,
190                                            NULL);
191   pmc_p2 = GNUNET_TRANSPORT_monitor_peers (ccc->p[1]->cfg,
192                                            NULL,
193                                            GNUNET_NO,
194                                            &monitor2_cb,
195                                            NULL);
196 }
197
198
199 int
200 main (int argc, char *argv[])
201 {
202   struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext my_ccc = {
203     .pre_connect_task = &start_monitors,
204     .connect_continuation = &sendtask,
205     .config_file = "test_transport_api_data.conf",
206     .rec = &notify_receive,
207     .nc = &notify_connect,
208     .nd = &GNUNET_TRANSPORT_TESTING_log_disconnect,
209     .shutdown_task = &custom_shutdown,
210     .timeout = TIMEOUT
211   };
212
213   ccc = &my_ccc;
214   if (GNUNET_OK !=
215       GNUNET_TRANSPORT_TESTING_main (2,
216                                      &GNUNET_TRANSPORT_TESTING_connect_check,
217                                      ccc))
218     return 1;
219   return 0;
220 }
221
222 /* end of test_transport_api_monitor_peers.c */