Changed logging for testcase
[oweals/gnunet.git] / src / mesh / test_mesh_2dtorus.c
1 /*
2      This file is part of GNUnet.
3      (C) 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 mesh/test_mesh_2dtorus.c
22  *
23  * @brief Test for creating a 2dtorus.
24  */
25 #include "platform.h"
26 #include "gnunet_testing_lib.h"
27
28 #define VERBOSE GNUNET_YES
29 #define REMOVE_DIR GNUNET_YES
30
31 /**
32  * How long until we give up on connecting the peers?
33  */
34 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1500)
35
36 /**
37  * Time to wait for stuff that should be rather fast
38  */
39 #define SHORT_TIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
40
41
42 /**
43  * How many events have happened
44  */
45 static int ok;
46
47 /**
48  * Be verbose
49  */
50 static int verbose;
51
52 /**
53  * Total number of peers in the test.
54  */
55 static unsigned long long num_peers;
56
57 /**
58  * Global configuration file
59  */
60 static struct GNUNET_CONFIGURATION_Handle *testing_cfg;
61
62 /**
63  * Total number of currently running peers.
64  */
65 static unsigned long long peers_running;
66
67 /**
68  * Total number of successful connections in the whole network.
69  */
70 static unsigned int total_connections;
71
72 /**
73  * Total number of counted topo connections
74  */
75 static unsigned int topo_connections;
76
77 /**
78  * Total number of failed connections in the whole network.
79  */
80 static unsigned int failed_connections;
81
82 /**
83  * The currently running peer group.
84  */
85 static struct GNUNET_TESTING_PeerGroup *pg;
86
87 /**
88  * Task called to disconnect peers
89  */
90 static GNUNET_SCHEDULER_TaskIdentifier disconnect_task;
91
92 /**
93  * Task called to shutdown test.
94  */
95 static GNUNET_SCHEDULER_TaskIdentifier shutdown_handle;
96
97
98 /**
99  * Check whether peers successfully shut down.
100  */
101 static void
102 shutdown_callback (void *cls, const char *emsg)
103 {
104   if (emsg != NULL)
105   {
106     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
107                 "test: Shutdown of peers failed! (%s)\n",
108                 emsg);
109     ok--;
110   }
111 #if VERBOSE
112   else
113   {
114     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
115                 "test: All peers successfully shut down!\n");
116   }
117 #endif
118 }
119
120
121 static void
122 shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
123 {
124 #if VERBOSE
125   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
126               "test: Ending test.\n");
127 #endif
128
129   GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL);
130   GNUNET_CONFIGURATION_destroy (testing_cfg);
131 }
132
133
134 static void
135 disconnect_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
136 {
137   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
138               "test: disconnecting peers\n");
139
140   if (GNUNET_SCHEDULER_NO_TASK != shutdown_handle)
141   {
142     GNUNET_SCHEDULER_cancel (shutdown_handle);
143     shutdown_handle = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL);
144   }
145 }
146
147
148 /**
149  * Prototype of a callback function indicating that two peers
150  * are currently connected.
151  *
152  * @param cls closure
153  * @param first peer id for first daemon
154  * @param second peer id for the second daemon
155  * @param distance distance between the connected peers
156  * @param emsg error message (NULL on success)
157  */
158 void
159 topo_cb (void *cls, const struct GNUNET_PeerIdentity *first,
160          const struct GNUNET_PeerIdentity *second, const char *emsg)
161 {
162   topo_connections++;
163   if (NULL != emsg)
164   {
165     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
166                 "test: Error by topo %u: %s\n",
167                 topo_connections, emsg);
168   }
169   else
170   {
171     if (first == NULL || second == NULL)
172     {
173       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
174                   "test: Connection %u NULL\n",
175                   topo_connections);
176       if (disconnect_task != GNUNET_SCHEDULER_NO_TASK)
177       {
178         GNUNET_SCHEDULER_cancel (disconnect_task);
179         GNUNET_SCHEDULER_add_now(&disconnect_peers, NULL);
180       }
181       return;
182     }
183     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
184                 "test: Connection %u ok\n",
185                 topo_connections);
186     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
187                 "test:   %s\n",
188                 GNUNET_i2s (first));
189     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
190                 "test:   %s\n",
191                 GNUNET_i2s (second));
192   }
193 }
194
195
196 /**
197  * peergroup_ready: start test when all peers are connected
198  * @param cls closure
199  * @param emsg error message
200  */
201 static void
202 peergroup_ready (void *cls, const char *emsg)
203 {
204   if (emsg != NULL)
205   {
206     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
207                 "test: Peergroup callback called with error, aborting test!\n");
208     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
209                 "test: Error from testing: `%s'\n", emsg);
210     ok--;
211     GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL);
212     return;
213   }
214 #if VERBOSE
215   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
216               "************************************************************\n");
217   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
218               "test: Peer Group started successfully!\n");
219   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
220               "test: Have %u connections\n",
221               total_connections);
222 #endif
223
224   peers_running = GNUNET_TESTING_daemons_running (pg);
225   if (0 < failed_connections)
226   {
227     ok = GNUNET_SYSERR;
228     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
229                 "test: %u connections have FAILED!\n",
230                 failed_connections);
231     disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_peers, NULL);
232
233   }
234   else
235   {
236     GNUNET_TESTING_get_topology (pg, &topo_cb, NULL);
237     disconnect_task =
238         GNUNET_SCHEDULER_add_delayed (SHORT_TIME, &disconnect_peers, NULL);
239     ok = GNUNET_OK;
240   }
241
242 }
243
244
245 /**
246  * Function that will be called whenever two daemons are connected by
247  * the testing library.
248  *
249  * @param cls closure
250  * @param first peer id for first daemon
251  * @param second peer id for the second daemon
252  * @param distance distance between the connected peers
253  * @param first_cfg config for the first daemon
254  * @param second_cfg config for the second daemon
255  * @param first_daemon handle for the first daemon
256  * @param second_daemon handle for the second daemon
257  * @param emsg error message (NULL on success)
258  */
259 static void
260 connect_cb (void *cls, const struct GNUNET_PeerIdentity *first,
261             const struct GNUNET_PeerIdentity *second, uint32_t distance,
262             const struct GNUNET_CONFIGURATION_Handle *first_cfg,
263             const struct GNUNET_CONFIGURATION_Handle *second_cfg,
264             struct GNUNET_TESTING_Daemon *first_daemon,
265             struct GNUNET_TESTING_Daemon *second_daemon, const char *emsg)
266 {
267   if (emsg == NULL)
268   {
269     total_connections++;
270   }
271   else
272   {
273     failed_connections++;
274     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
275                 "test: Problem with new connection (%s)\n",
276                 emsg);
277     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test:   (%s)\n",
278                 GNUNET_i2s (first));
279     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test:   (%s)\n",
280                 GNUNET_i2s (second));
281   }
282
283 }
284
285
286 /**
287  * run: load configuration options and schedule test to run (start peergroup)
288  * @param cls closure
289  * @param args argv
290  * @param cfgfile configuration file name (can be NULL)
291  * @param cfg configuration handle
292  */
293 static void
294 run (void *cls, char *const *args, const char *cfgfile,
295      const struct GNUNET_CONFIGURATION_Handle *cfg)
296 {
297   struct GNUNET_TESTING_Host *hosts;
298
299   ok = GNUNET_NO;
300   total_connections = 0;
301   failed_connections = 0;
302   testing_cfg = GNUNET_CONFIGURATION_dup (cfg);
303
304   GNUNET_log_setup ("test_mesh_2dtorus",
305 #if VERBOSE
306                     "DEBUG",
307 #else
308                     "WARNING",
309 #endif
310                     NULL);
311
312 #if VERBOSE
313   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
314               "test: Starting daemons.\n");
315   GNUNET_CONFIGURATION_set_value_string (testing_cfg, "testing",
316                                          "use_progressbars", "YES");
317 #endif
318
319   if (GNUNET_OK !=
320       GNUNET_CONFIGURATION_get_value_number (testing_cfg, "testing",
321                                              "num_peers", &num_peers))
322   {
323     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
324                 "Option TESTING:NUM_PEERS is required!\n");
325     return;
326   }
327
328   hosts = GNUNET_TESTING_hosts_load (testing_cfg);
329
330   pg = GNUNET_TESTING_peergroup_start (testing_cfg, num_peers, TIMEOUT,
331                                        &connect_cb, &peergroup_ready, NULL,
332                                        hosts);
333   GNUNET_assert (pg != NULL);
334   shutdown_handle =
335       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_get_forever (),
336                                     &shutdown_task, NULL);
337 }
338
339
340 /**
341  * test_mesh_2dtorus command line options
342  */
343 static struct GNUNET_GETOPT_CommandLineOption options[] = {
344   {'V', "verbose", NULL,
345    gettext_noop ("be verbose (print progress information)"),
346    0, &GNUNET_GETOPT_set_one, &verbose},
347   GNUNET_GETOPT_OPTION_END
348 };
349
350
351 /**
352  * Main: start test
353  */
354 int
355 main (int argc, char *argv[])
356 {
357   char *const argv2[] = {
358     argv[0],
359     "-c",
360     "test_mesh_2dtorus.conf",
361 #if VERBOSE
362     "-L",
363     "DEBUG",
364 #endif
365     NULL
366   };
367
368   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Start\n");
369
370
371   GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
372                       "test_mesh_2dtorus",
373                       gettext_noop ("Test mesh 2d torus."), options,
374                       &run, NULL);
375 #if REMOVE_DIR
376   GNUNET_DISK_directory_remove ("/tmp/test_mesh_2dtorus");
377 #endif
378   if (GNUNET_OK != ok)
379   {
380     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
381                 "test: FAILED!\n");
382     return 1;
383   }
384   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: success\n");
385   return 0;
386 }
387
388 /* end of test_mesh_2dtorus.c */