taking care of send msg size in the api
[oweals/gnunet.git] / src / rps / test_rps_multipeer.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009, 2012 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 rps/test_rps_multipeer.c
22  * @brief Testcase for the random peer sampling service.  Starts
23  *        a peergroup with a given number of peers, then waits to
24  *        receive size pushes/pulls from each peer.  Expects to wait
25  *        for one message from each peer.
26  */
27 #include "platform.h"
28 #include "gnunet_testbed_service.h"
29 #include "gnunet_rps_service.h"
30 #include <time.h>
31
32
33 /**
34  * How many peers do we start?
35  */
36 #define NUM_PEERS 5
37
38 /**
39  * How long do we run the test?
40  */
41 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60)
42
43
44 /**
45  * Portion of malicious peers
46  */
47 static double portion = .1;
48
49
50 /**
51  * Information we track for each peer.
52  */
53 struct RPSPeer
54 {
55   /**
56    * Handle for RPS connect operation.
57    */
58   struct GNUNET_TESTBED_Operation *op;
59
60   /**
61    * Handle to RPS service.
62    */
63   struct GNUNET_RPS_Handle *rps_handle;
64 };
65
66
67 /**
68  * Information for all the peers.
69  */
70 static struct RPSPeer rps_peers[NUM_PEERS];
71
72 /**
73  * IDs of the peers.
74  */
75 static struct GNUNET_PeerIdentity rps_peer_ids[NUM_PEERS];
76
77 /**
78  * Return value from 'main'.
79  */
80 static int ok;
81
82
83 /**
84  * Task run on timeout to shut everything down.
85  */
86 static void
87 shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
88 {
89   unsigned int i;
90
91   for (i=0;i<NUM_PEERS;i++)
92     GNUNET_TESTBED_operation_done (rps_peers[i].op);
93   GNUNET_SCHEDULER_shutdown ();
94 }
95
96
97 /**
98  * Callback to call when network size estimate is updated.
99  *
100  * @param cls closure
101  * @param timestamp server timestamp
102  * @param estimate the value of the current network size estimate
103  * @param std_dev standard deviation (rounded down to nearest integer)
104  *                of the size estimation values seen
105  *
106  */
107 static void
108 handle_reply (void *cls, uint64_t n, const struct GNUNET_PeerIdentity *peers)
109 {
110   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got peer %s\n", GNUNET_i2s (peers));
111   
112   ok = 0;
113 }
114
115
116 /**
117  * (Randomly) request random peers.
118  */
119   void
120 request_peers (void *cls,
121                const struct GNUNET_SCHEDULER_TaskContext *tc)
122 {
123   struct RPSPeer *peer = (struct RPSPeer *) cls;
124
125   GNUNET_RPS_request_peers (peer->rps_handle, 1, handle_reply, NULL);
126 }
127
128
129 /**
130  * Seed peers.
131  */
132   void
133 seed_peers (void *cls,
134                const struct GNUNET_SCHEDULER_TaskContext *tc)
135 {
136   unsigned int amount;
137   struct RPSPeer *peer = (struct RPSPeer *) cls;
138
139   GNUNET_assert (1 >= portion &&
140                  0 <  portion);
141                 
142   amount = portion * NUM_PEERS;
143
144   // TODO log
145
146   GNUNET_RPS_seed_ids (peer->rps_handle, amount, rps_peer_ids);
147 }
148
149
150 /**
151  * Get the id of peer i.
152  */
153   void
154 info_cb (void *cb_cls,
155          struct GNUNET_TESTBED_Operation *op,
156          const struct GNUNET_TESTBED_PeerInformation *pinfo,
157          const char *emsg)
158 {
159   unsigned int *i = (unsigned int *) cb_cls;
160
161   if (NULL == pinfo || NULL != emsg)
162   {
163     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Got Error: %s\n", emsg);
164     return;
165   }
166
167   rps_peer_ids[*i] = *(pinfo->result.id);
168
169   GNUNET_free (cb_cls);
170 }
171
172
173 /**
174  * Callback to be called when RPS service connect operation is completed
175  *
176  * @param cls the callback closure from functions generating an operation
177  * @param op the operation that has been finished
178  * @param ca_result the RPS service handle returned from rps_connect_adapter
179  * @param emsg error message in case the operation has failed; will be NULL if
180  *          operation has executed successfully.
181  */
182 static void
183 rps_connect_complete_cb (void *cls,
184                          struct GNUNET_TESTBED_Operation *op,
185                          void *ca_result,
186                          const char *emsg)
187 {
188   struct RPSPeer *peer = cls;
189   struct GNUNET_RPS_Handle *rps = ca_result;
190   peer->rps_handle = rps;
191
192   GNUNET_assert (op == peer->op);
193   if (NULL != emsg)
194     {
195       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
196                   "Failed to connect to RPS service: %s\n",
197                   emsg);
198       ok = 1;
199       GNUNET_SCHEDULER_shutdown ();
200       return;
201     }
202   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Started client successfully\n");
203
204   GNUNET_RPS_request_peers (rps, 1, handle_reply, NULL);
205
206   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10),
207                                 request_peers, peer);
208   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10),
209                                 seed_peers, peer);
210   // TODO test seeding > GNUNET_SERVER_MAX_MESSAGE_SIZE peers
211 }
212
213
214 /**
215  * Adapter function called to establish a connection to
216  * the RPS service.
217  *
218  * @param cls closure
219  * @param cfg configuration of the peer to connect to; will be available until
220  *          GNUNET_TESTBED_operation_done() is called on the operation returned
221  *          from GNUNET_TESTBED_service_connect()
222  * @return service handle to return in 'op_result', NULL on error
223  */
224 static void *
225 rps_connect_adapter (void *cls,
226                      const struct GNUNET_CONFIGURATION_Handle *cfg)
227 {
228   return GNUNET_RPS_connect (cfg);
229 }
230
231
232 /**
233  * Adapter function called to destroy connection to
234  * RPS service.
235  *
236  * @param cls closure
237  * @param op_result service handle returned from the connect adapter
238  */
239 static void
240 rps_disconnect_adapter (void *cls,
241                         void *op_result)
242 {
243   struct GNUNET_RPS_Handle *h = op_result;
244   GNUNET_RPS_disconnect (h);
245 }
246
247
248 /**
249  * Actual "main" function for the testcase.
250  *
251  * @param cls closure
252  * @param h the run handle
253  * @param num_peers number of peers in 'peers'
254  * @param peers handle to peers run in the testbed
255  * @param links_succeeded the number of overlay link connection attempts that
256  *          succeeded
257  * @param links_failed the number of overlay link connection attempts that
258  *          failed
259  */
260 static void
261 run (void *cls,
262      struct GNUNET_TESTBED_RunHandle *h,
263      unsigned int num_peers,
264      struct GNUNET_TESTBED_Peer **peers,
265      unsigned int links_succeeded,
266      unsigned int links_failed)
267 {
268   unsigned int i;
269   unsigned int *tmp_i;
270
271   for ( i = 0 ; i < NUM_PEERS ; i++ )
272   {
273     tmp_i = GNUNET_new (unsigned int);
274     *tmp_i = i;
275
276     (void) GNUNET_TESTBED_peer_get_information (peers[i],
277                                                 GNUNET_TESTBED_PIT_IDENTITY,
278                                                 &info_cb, tmp_i);
279   }
280
281   GNUNET_assert (NUM_PEERS == num_peers);
282   for (i=0;i<num_peers;i++)
283     //rps_peers[i].peer_index = i;
284     rps_peers[i].op = GNUNET_TESTBED_service_connect (&rps_peers[i],
285                                                       peers[i],
286                                                       "rps",
287                                                       &rps_connect_complete_cb,
288                                                       &rps_peers[i],
289                                                       &rps_connect_adapter,
290                                                       &rps_disconnect_adapter,
291                                                       &rps_peers[i]);
292   GNUNET_SCHEDULER_add_delayed (TIMEOUT, &shutdown_task, NULL);
293 }
294
295
296 /**
297  * Entry point for the testcase, sets up the testbed.
298  *
299  * @param argc unused
300  * @param argv unused
301  * @return 0 on success
302  */
303 int
304 main (int argc, char *argv[])
305 {
306   ok = 1;
307   (void) GNUNET_TESTBED_test_run ("test-rps-multipeer",
308                                   "test_rps.conf",
309                                   NUM_PEERS,
310                                   0, NULL, NULL,
311                                   &run, NULL);
312   return ok;
313 }
314
315 /* end of test_rps_multipeer.c */