restructured test, testing seed
[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 }
211
212
213 /**
214  * Adapter function called to establish a connection to
215  * the RPS service.
216  *
217  * @param cls closure
218  * @param cfg configuration of the peer to connect to; will be available until
219  *          GNUNET_TESTBED_operation_done() is called on the operation returned
220  *          from GNUNET_TESTBED_service_connect()
221  * @return service handle to return in 'op_result', NULL on error
222  */
223 static void *
224 rps_connect_adapter (void *cls,
225                      const struct GNUNET_CONFIGURATION_Handle *cfg)
226 {
227   return GNUNET_RPS_connect (cfg);
228 }
229
230
231 /**
232  * Adapter function called to destroy connection to
233  * RPS service.
234  *
235  * @param cls closure
236  * @param op_result service handle returned from the connect adapter
237  */
238 static void
239 rps_disconnect_adapter (void *cls,
240                         void *op_result)
241 {
242   struct GNUNET_RPS_Handle *h = op_result;
243   GNUNET_RPS_disconnect (h);
244 }
245
246
247 /**
248  * Actual "main" function for the testcase.
249  *
250  * @param cls closure
251  * @param h the run handle
252  * @param num_peers number of peers in 'peers'
253  * @param peers handle to peers run in the testbed
254  * @param links_succeeded the number of overlay link connection attempts that
255  *          succeeded
256  * @param links_failed the number of overlay link connection attempts that
257  *          failed
258  */
259 static void
260 run (void *cls,
261      struct GNUNET_TESTBED_RunHandle *h,
262      unsigned int num_peers,
263      struct GNUNET_TESTBED_Peer **peers,
264      unsigned int links_succeeded,
265      unsigned int links_failed)
266 {
267   unsigned int i;
268   unsigned int *tmp_i;
269
270   for ( i = 0 ; i < NUM_PEERS ; i++ )
271   {
272     tmp_i = GNUNET_new (unsigned int);
273     *tmp_i = i;
274
275     (void) GNUNET_TESTBED_peer_get_information (peers[i],
276                                                 GNUNET_TESTBED_PIT_IDENTITY,
277                                                 &info_cb, tmp_i);
278   }
279
280   GNUNET_assert (NUM_PEERS == num_peers);
281   for (i=0;i<num_peers;i++)
282     //rps_peers[i].peer_index = i;
283     rps_peers[i].op = GNUNET_TESTBED_service_connect (&rps_peers[i],
284                                                       peers[i],
285                                                       "rps",
286                                                       &rps_connect_complete_cb,
287                                                       &rps_peers[i],
288                                                       &rps_connect_adapter,
289                                                       &rps_disconnect_adapter,
290                                                       &rps_peers[i]);
291   GNUNET_SCHEDULER_add_delayed (TIMEOUT, &shutdown_task, NULL);
292 }
293
294
295 /**
296  * Entry point for the testcase, sets up the testbed.
297  *
298  * @param argc unused
299  * @param argv unused
300  * @return 0 on success
301  */
302 int
303 main (int argc, char *argv[])
304 {
305   ok = 1;
306   (void) GNUNET_TESTBED_test_run ("test-rps-multipeer",
307                                   "test_rps.conf",
308                                   NUM_PEERS,
309                                   0, NULL, NULL,
310                                   &run, NULL);
311   return ok;
312 }
313
314 /* end of test_rps_multipeer.c */