first batch of license fixes (boring)
[oweals/gnunet.git] / src / nse / test_nse_multipeer.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2009, 2012 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU 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 /**
16  * @file nse/test_nse_multipeer.c
17  * @brief Testcase for the network size estimation service.  Starts
18  *        a peergroup with a given number of peers, then waits to
19  *        receive size estimates from each peer.  Expects to wait
20  *        for one message from each peer.
21  */
22 #include "platform.h"
23 #include "gnunet_testbed_service.h"
24 #include "gnunet_nse_service.h"
25
26
27 /**
28  * How many peers do we start?
29  */
30 #define NUM_PEERS 4
31
32 /**
33  * How long do we run the test?
34  */
35 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300)
36
37
38 /**
39  * Information we track for each peer.
40  */
41 struct NSEPeer
42 {
43   /**
44    * Handle for NSE connect operation.
45    */
46   struct GNUNET_TESTBED_Operation *op;
47
48   /**
49    * Handle to NSE service.
50    */
51   struct GNUNET_NSE_Handle *nse_handle;
52 };
53
54
55 /**
56  * Information for all the peers.
57  */
58 static struct NSEPeer nse_peers[NUM_PEERS];
59
60 /**
61  * Return value from 'main'.
62  */
63 static int ok;
64
65
66 /**
67  * Task run on timeout to shut everything down.
68  */
69 static void
70 shutdown_task (void *cls)
71 {
72   unsigned int i;
73
74   for (i=0;i<NUM_PEERS;i++)
75     GNUNET_TESTBED_operation_done (nse_peers[i].op);
76   GNUNET_SCHEDULER_shutdown ();
77 }
78
79
80 /**
81  * Callback to call when network size estimate is updated.
82  *
83  * @param cls closure
84  * @param timestamp server timestamp
85  * @param estimate the value of the current network size estimate
86  * @param std_dev standard deviation (rounded down to nearest integer)
87  *                of the size estimation values seen
88  *
89  */
90 static void
91 handle_estimate (void *cls, struct GNUNET_TIME_Absolute timestamp,
92                  double estimate, double std_dev)
93 {
94   struct NSEPeer *peer = cls;
95
96   FPRINTF (stderr,
97            "Received network size estimate from peer %u. logSize: %f std.dev. %f (%f/%u)\n",
98            (unsigned int) (peer - nse_peers),
99            estimate, std_dev,
100            GNUNET_NSE_log_estimate_to_n (estimate),
101            NUM_PEERS);
102   ok = 0;
103 }
104
105
106 /**
107  * Callback to be called when NSE service connect operation is completed
108  *
109  * @param cls the callback closure from functions generating an operation
110  * @param op the operation that has been finished
111  * @param ca_result the NSE service handle returned from nse_connect_adapter
112  * @param emsg error message in case the operation has failed; will be NULL if
113  *          operation has executed successfully.
114  */
115 static void
116 nse_connect_complete_cb (void *cls,
117                          struct GNUNET_TESTBED_Operation *op,
118                          void *ca_result,
119                          const char *emsg)
120 {
121   struct NSEPeer *peer = cls;
122   struct GNUNET_NSE_Handle *nse = ca_result;
123
124   GNUNET_assert (op == peer->op);
125   if (NULL != emsg)
126     {
127       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
128                   "Failed to connect to NSE service: %s\n",
129                   emsg);
130       ok = 1;
131       GNUNET_SCHEDULER_shutdown ();
132       return;
133     }
134   peer->nse_handle = nse;
135 }
136
137
138 /**
139  * Adapter function called to establish a connection to
140  * the NSE service.
141  *
142  * @param cls closure
143  * @param cfg configuration of the peer to connect to; will be available until
144  *          GNUNET_TESTBED_operation_done() is called on the operation returned
145  *          from GNUNET_TESTBED_service_connect()
146  * @return service handle to return in 'op_result', NULL on error
147  */
148 static void *
149 nse_connect_adapter (void *cls,
150                      const struct GNUNET_CONFIGURATION_Handle *cfg)
151 {
152   return GNUNET_NSE_connect (cfg,
153                              &handle_estimate,
154                              cls);
155 }
156
157
158 /**
159  * Adapter function called to destroy connection to
160  * NSE service.
161  *
162  * @param cls closure
163  * @param op_result service handle returned from the connect adapter
164  */
165 static void
166 nse_disconnect_adapter (void *cls,
167                         void *op_result)
168 {
169   GNUNET_NSE_disconnect (op_result);
170 }
171
172
173 /**
174  * Actual "main" function for the testcase.
175  *
176  * @param cls closure
177  * @param h the run handle
178  * @param num_peers number of peers in 'peers'
179  * @param peers handle to peers run in the testbed
180  * @param links_succeeded the number of overlay link connection attempts that
181  *          succeeded
182  * @param links_failed the number of overlay link connection attempts that
183  *          failed
184  */
185 static void
186 run (void *cls,
187      struct GNUNET_TESTBED_RunHandle *h,
188      unsigned int num_peers,
189      struct GNUNET_TESTBED_Peer **peers,
190      unsigned int links_succeeded,
191      unsigned int links_failed)
192 {
193   unsigned int i;
194
195   GNUNET_assert (NUM_PEERS == num_peers);
196   for (i=0;i<num_peers;i++)
197     nse_peers[i].op = GNUNET_TESTBED_service_connect (&nse_peers[i],
198                                                       peers[i],
199                                                       "nse",
200                                                       &nse_connect_complete_cb,
201                                                       &nse_peers[i],
202                                                       &nse_connect_adapter,
203                                                       &nse_disconnect_adapter,
204                                                       &nse_peers[i]);
205   GNUNET_SCHEDULER_add_delayed (TIMEOUT,
206                                 &shutdown_task, NULL);
207 }
208
209
210 /**
211  * Entry point for the testcase, sets up the testbed.
212  *
213  * @param argc unused
214  * @param argv unused
215  * @return 0 on success
216  */
217 int
218 main (int argc, char *argv[])
219 {
220   ok = 1;
221   (void) GNUNET_TESTBED_test_run ("test-nse-multipeer",
222                                   "test_nse.conf",
223                                   NUM_PEERS,
224                                   0, NULL, NULL,
225                                   &run, NULL);
226   return ok;
227 }
228
229 /* end of test_nse_multipeer.c */