changes to perf
[oweals/gnunet.git] / src / ats / perf_ats_mlp.c
1 /*
2      This file is part of GNUnet.
3      (C) 2010,2011 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 ats/perf_ats_mlp
22  * @brief performance test for the MLP solver
23  * @author Christian Grothoff
24  * @author Matthias Wachs
25
26  */
27
28 /*
29      This file is part of GNUnet.
30      (C) 2010,2011 Christian Grothoff (and other contributing authors)
31
32      GNUnet is free software; you can redistribute it and/or modify
33      it under the terms of the GNU General Public License as published
34      by the Free Software Foundation; either version 3, or (at your
35      option) any later version.
36
37      GNUnet is distributed in the hope that it will be useful, but
38      WITHOUT ANY WARRANTY; without even the implied warranty of
39      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
40      General Public License for more details.
41
42      You should have received a copy of the GNU General Public License
43      along with GNUnet; see the file COPYING.  If not, write to the
44      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
45      Boston, MA 02111-1307, USA.
46 */
47 /**
48  * @file ats/test_ats_mlp.c
49  * @brief basic test for the MLP solver
50  * @author Christian Grothoff
51  * @author Matthias Wachs
52
53  */
54 #include "platform.h"
55 #include "gnunet_util_lib.h"
56 #include "gnunet_statistics_service.h"
57 #include "gnunet_ats_service.h"
58 #include "gnunet-service-ats_addresses_mlp.h"
59 #include "test_ats_api_common.h"
60
61 #define PEERS_START 1
62 #define PEERS_END       100
63
64 /**
65  * Return value
66  */
67 static int ret;
68
69 /**
70  * MLP solver handle
71  */
72 struct GAS_MLP_Handle *mlp;
73
74
75 /**
76  * Statistics handle
77  */
78 struct GNUNET_STATISTICS_Handle * stats;
79
80 /**
81  * Hashmap containing addresses
82  */
83 struct GNUNET_CONTAINER_MultiHashMap * addresses;
84
85 /**
86  * Peer
87  */
88 struct GNUNET_PeerIdentity p[2];
89
90 /**
91  * ATS Address
92  */
93 struct ATS_Address *address[3];
94
95 /**
96  * Timeout task
97  */
98 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
99
100
101 #if 0
102
103 #define MLP_MAX_EXEC_DURATION   GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3)
104 #define MLP_MAX_ITERATIONS      INT_MAX
105
106 static void
107 set_ats (struct GNUNET_ATS_Information *ats, uint32_t type, uint32_t value)
108 {
109   ats->type = type;
110   ats->value = value;
111 }
112
113 #endif
114
115 int addr_it (void *cls,
116              const struct GNUNET_HashCode * key,
117              void *value)
118 {
119         struct ATS_Address *address = (struct ATS_Address *) value;
120         GAS_mlp_address_delete (mlp, addresses, address, GNUNET_NO);
121         GNUNET_CONTAINER_multihashmap_remove (addresses, key, value);
122   GNUNET_free (address);
123         return GNUNET_OK;
124 }
125
126
127 static void
128 end_now (int res)
129 {
130         if (GNUNET_SCHEDULER_NO_TASK != timeout_task)
131         {
132                         GNUNET_SCHEDULER_cancel (timeout_task);
133                         timeout_task = GNUNET_SCHEDULER_NO_TASK;
134         }
135   if (NULL != stats)
136   {
137           GNUNET_STATISTICS_destroy(stats, GNUNET_NO);
138           stats = NULL;
139   }
140   if (NULL != addresses)
141   {
142                 GNUNET_CONTAINER_multihashmap_iterate (addresses, &addr_it, NULL);
143                 GNUNET_CONTAINER_multihashmap_destroy (addresses);
144                 addresses = NULL ;
145   }
146   if (NULL != mlp)
147   {
148                 GAS_mlp_done (mlp);
149                 mlp = NULL;
150   }
151
152         ret = res;
153 }
154
155 static void
156 end_correctly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
157 {
158   GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Test ending with success\n"));
159         end_now (0);
160 }
161
162 static void
163 end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
164 {
165         timeout_task = GNUNET_SCHEDULER_NO_TASK;
166   GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Test ending with timeout\n"));
167         end_now (1);
168 }
169
170
171 static void
172 bandwidth_changed_cb (void *cls, struct ATS_Address *address)
173 {
174         static int cb_p0 = GNUNET_NO;
175         static int cb_p1 = GNUNET_NO;
176
177         unsigned long long in = ntohl(address->assigned_bw_in.value__);
178         unsigned long long out = ntohl(address->assigned_bw_out.value__);
179
180   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MLP suggests for peer `%s' address `%s':`%s' in %llu out %llu \n",
181                 GNUNET_i2s(&address->peer),
182                 address->plugin,
183                 address->addr,
184                 in, out);
185
186   if ((in > 0) && (out > 0) &&
187                 (0 == memcmp(&p[0], &address->peer, sizeof (address->peer))))
188         cb_p0 ++;
189
190   if ((in > 0) && (out > 0) &&
191                 (0 == memcmp(&p[1], &address->peer, sizeof (address->peer))))
192         cb_p1 ++;
193
194   if ((1 == cb_p0) && (1 == cb_p1))
195                 GNUNET_SCHEDULER_add_now (&end_correctly, NULL);
196   else if ((1 > cb_p0) || (1 > cb_p1))
197                 GNUNET_SCHEDULER_add_now (&end_badly, NULL);
198 }
199
200
201 static void
202 check (void *cls, char *const *args, const char *cfgfile,
203        const struct GNUNET_CONFIGURATION_Handle *cfg)
204 {
205   int quotas[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkType;
206   unsigned long long  quotas_in[GNUNET_ATS_NetworkTypeCount];
207   unsigned long long  quotas_out[GNUNET_ATS_NetworkTypeCount];
208   //struct GNUNET_ATS_Information ats;
209
210 #if !HAVE_LIBGLPK
211   GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "GLPK not installed!");
212   ret = 1;
213   return;
214 #endif
215
216
217
218   timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
219
220   stats = GNUNET_STATISTICS_create("ats", cfg);
221   if (NULL == stats)
222   {
223         GNUNET_break (0);
224     end_now (1);
225     return;
226   }
227
228   /* Load quotas */
229   if (GNUNET_ATS_NetworkTypeCount != load_quotas (cfg, quotas_out, quotas_in,
230                         GNUNET_ATS_NetworkTypeCount))
231   {
232         GNUNET_break (0);
233       end_now (1);
234       return;
235   }
236
237   /* Setup address hashmap */
238   addresses = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO);
239
240   /* Init MLP solver */
241   mlp  = GAS_mlp_init (cfg, stats, quotas, quotas_out, quotas_in,
242                 GNUNET_ATS_NetworkTypeCount, &bandwidth_changed_cb, NULL);
243   if (NULL == mlp)
244   {
245         GNUNET_break (0);
246       end_now (1);
247       return;
248   }
249   mlp->mlp_auto_solve = GNUNET_NO;
250
251
252 #if 0
253
254   /* Create peer 0 */
255   if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID0, &p[0].hashPubKey))
256   {
257       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n");
258       end_now (1);
259       return;
260   }
261
262   /* Create peer 1 */
263   if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID1, &p[1].hashPubKey))
264   {
265       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n");
266       end_now (1);
267       return;
268   }
269
270   /* Create address 0 */
271   address[0] = create_address (&p[0], "test_plugin0", "test_addr0", strlen("test_addr0")+1, 0);
272   if (NULL == address[0])
273   {
274         GNUNET_break (0);
275       end_now (1);
276       return;
277   }
278   GNUNET_CONTAINER_multihashmap_put (addresses, &p[0].hashPubKey, address[0],
279                 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
280   /* Adding address 0 */
281   GAS_mlp_address_add (mlp, addresses, address[0]);
282
283   /* Create address 1 */
284   address[1] = create_address (&p[0], "test_plugin1", "test_addr1", strlen("test_addr1")+1, 0);
285   if (NULL == address[1])
286   {
287         GNUNET_break (0);
288       end_now (1);
289       return;
290   }
291   GNUNET_CONTAINER_multihashmap_put (addresses, &p[0].hashPubKey, address[1],
292                 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
293   /* Adding address 1*/
294   GAS_mlp_address_add (mlp, addresses, address[1]);
295
296
297   /* Create address 3 */
298   address[2] = create_address (&p[1], "test_plugin2", "test_addr2", strlen("test_addr2")+1, 0);
299   if (NULL == address[2])
300   {
301         GNUNET_break (0);
302       end_now (1);
303       return;
304   }
305   GNUNET_CONTAINER_multihashmap_put (addresses, &p[1].hashPubKey, address[2],
306                 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
307   /* Adding address 3*/
308   GAS_mlp_address_add (mlp, addresses, address[2]);
309
310
311   /* Updating address 0*/
312   ats.type =  htonl (GNUNET_ATS_NETWORK_TYPE);
313   ats.value = htonl (GNUNET_ATS_NET_WAN);
314   GAS_mlp_address_update (mlp, addresses, address[0], 1, GNUNET_NO, &ats, 1);
315
316   /* Retrieving preferred address for peer and wait for callback */
317   GAS_mlp_get_preferred_address (mlp, addresses, &p[0]);
318   GAS_mlp_get_preferred_address (mlp, addresses, &p[1]);
319
320   GAS_mlp_solve_problem (mlp, addresses);
321 #endif
322 }
323
324
325 int
326 main (int argc, char *argv[])
327 {
328
329   static char *const argv2[] = { "perf_ats_mlp",
330     "-c",
331     "test_ats_mlp.conf",
332     "-L", "WARNING",
333     NULL
334   };
335
336   static struct GNUNET_GETOPT_CommandLineOption options[] = {
337     GNUNET_GETOPT_OPTION_END
338   };
339
340   GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
341                       "perf_ats_mlp", "nohelp", options,
342                       &check, NULL);
343
344
345   return ret;
346 }
347
348 /* end of file test_ats_api_bandwidth_consumption.c */
349
350
351 /* end of file perf_ats_mlp.c */