-ensure stats queues do not grow too big
[oweals/gnunet.git] / src / testbed / test_gnunet_helper_testbed.c
1 /*
2       This file is part of GNUnet
3       Copyright (C) 2008--2013 GNUnet e.V.
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., 51 Franklin Street, Fifth Floor,
18       Boston, MA 02110-1301, USA.
19  */
20
21 /**
22  * @file testbed/test_gnunet_helper_testbed.c
23  * @brief Testcase for testing gnunet-helper-testbed.c
24  * @author Sree Harsha Totakura <sreeharsha@totakura.in>
25  */
26
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_testbed_service.h"
30 #include <zlib.h>
31
32 #include "testbed_api.h"
33 #include "testbed_helper.h"
34 #include "testbed_api_hosts.h"
35
36 /**
37  * Generic logging shortcut
38  */
39 #define LOG(kind,...)                           \
40   GNUNET_log (kind, __VA_ARGS__)
41
42
43 /**
44  * Handle to the helper process
45  */
46 static struct GNUNET_HELPER_Handle *helper;
47
48 /**
49  * Message to helper
50  */
51 static struct GNUNET_TESTBED_HelperInit *msg;
52
53 /**
54  * Message send handle
55  */
56 static struct GNUNET_HELPER_SendHandle *shandle;
57
58 /**
59  * Abort task identifier
60  */
61 static struct GNUNET_SCHEDULER_Task * abort_task;
62
63 /**
64  * Shutdown task identifier
65  */
66 static struct GNUNET_SCHEDULER_Task * shutdown_task;
67
68 /**
69  * Configuratin handler
70  */
71 static struct GNUNET_CONFIGURATION_Handle *cfg;
72
73 /**
74  * Global testing status
75  */
76 static int result;
77
78
79 /**
80  * Shutdown nicely
81  *
82  * @param cls NULL
83  */
84 static void
85 do_shutdown (void *cls)
86 {
87   if (NULL != abort_task)
88     GNUNET_SCHEDULER_cancel (abort_task);
89   if (NULL != helper)
90     GNUNET_HELPER_stop (helper, GNUNET_NO);
91   GNUNET_free_non_null (msg);
92   if (NULL != cfg)
93     GNUNET_CONFIGURATION_destroy (cfg);
94 }
95
96
97 /**
98  * abort task to run on test timed out
99  *
100  * @param cls NULL
101  */
102 static void
103 do_abort (void *cls)
104 {
105   abort_task = NULL;
106   LOG (GNUNET_ERROR_TYPE_WARNING, "Test timedout -- Aborting\n");
107   result = GNUNET_SYSERR;
108   if (NULL != shandle)
109     GNUNET_HELPER_send_cancel (shandle);
110   if (NULL == shutdown_task)
111     shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
112 }
113
114
115 /**
116  * Continuation function.
117  *
118  * @param cls closure
119  * @param result #GNUNET_OK on success,
120  *               #GNUNET_NO if helper process died
121  *               #GNUNET_SYSERR during GNUNET_HELPER_stop()
122  */
123 static void
124 cont_cb (void *cls, int result)
125 {
126   shandle = NULL;
127   LOG (GNUNET_ERROR_TYPE_DEBUG, "Message sent\n");
128   GNUNET_assert (GNUNET_OK == result);
129 }
130
131
132 /**
133  * Functions with this signature are called whenever a
134  * complete message is received by the tokenizer.
135  *
136  * Do not call GNUNET_SERVER_mst_destroy in callback
137  *
138  * @param cls closure
139  * @param client identification of the client
140  * @param message the actual message
141  *
142  * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
143  */
144 static int
145 mst_cb (void *cls, void *client, const struct GNUNET_MessageHeader *message)
146 {
147   const struct GNUNET_TESTBED_HelperReply *msg;
148   char *config;
149   uLongf config_size;
150   uLongf xconfig_size;
151
152   msg = (const struct GNUNET_TESTBED_HelperReply *) message;
153   config_size = 0;
154   xconfig_size = 0;
155   GNUNET_assert (sizeof (struct GNUNET_TESTBED_HelperReply) <
156                  ntohs (msg->header.size));
157   GNUNET_assert (GNUNET_MESSAGE_TYPE_TESTBED_HELPER_REPLY ==
158                  ntohs (msg->header.type));
159   config_size = (uLongf) ntohs (msg->config_size);
160   xconfig_size =
161       (uLongf) (ntohs (msg->header.size) -
162                 sizeof (struct GNUNET_TESTBED_HelperReply));
163   config = GNUNET_malloc (config_size);
164   GNUNET_assert (Z_OK ==
165                  uncompress ((Bytef *) config, &config_size,
166                              (const Bytef *) &msg[1], xconfig_size));
167   GNUNET_free (config);
168   if (NULL == shutdown_task)
169     shutdown_task =
170         GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
171                                       (GNUNET_TIME_UNIT_SECONDS, 1),
172                                       &do_shutdown, NULL);
173   return GNUNET_OK;
174 }
175
176
177 /**
178  * Callback that will be called when the helper process dies. This is not called
179  * when the helper process is stoped using GNUNET_HELPER_stop()
180  *
181  * @param cls the closure from GNUNET_HELPER_start()
182  */
183 static void
184 exp_cb (void *cls)
185 {
186   helper = NULL;
187   result = GNUNET_SYSERR;
188 }
189
190
191 /**
192  * Main function that will be run.
193  *
194  * @param cls closure
195  * @param args remaining command-line arguments
196  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
197  * @param cfg configuration
198  */
199 static void
200 run (void *cls, char *const *args, const char *cfgfile,
201      const struct GNUNET_CONFIGURATION_Handle *cfg2)
202 {
203   static char *const binary_argv[] = {
204     "gnunet-helper-testbed",
205     NULL
206   };
207   const char *trusted_ip = "127.0.0.1";
208
209   helper =
210       GNUNET_HELPER_start (GNUNET_YES, "gnunet-helper-testbed", binary_argv,
211                            &mst_cb, &exp_cb, NULL);
212   GNUNET_assert (NULL != helper);
213   cfg = GNUNET_CONFIGURATION_dup (cfg2);
214   msg = GNUNET_TESTBED_create_helper_init_msg_ (trusted_ip, NULL, cfg);
215   shandle =
216       GNUNET_HELPER_send (helper, &msg->header, GNUNET_NO, &cont_cb, NULL);
217   GNUNET_assert (NULL != shandle);
218   abort_task =
219       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
220                                     (GNUNET_TIME_UNIT_MINUTES, 1), &do_abort,
221                                     NULL);
222 }
223
224
225 /**
226  * Main function
227  *
228  * @param argc the number of command line arguments
229  * @param argv command line arg array
230  * @return return code
231  */
232 int
233 main (int argc, char **argv)
234 {
235   struct GNUNET_GETOPT_CommandLineOption options[] = {
236     GNUNET_GETOPT_OPTION_END
237   };
238
239   result = GNUNET_OK;
240   if (GNUNET_OK !=
241       GNUNET_PROGRAM_run (argc, argv, "test_gnunet_helper_testbed",
242                           "Testcase for testing gnunet-helper-testbed.c",
243                           options, &run, NULL))
244     return 1;
245   return (GNUNET_OK == result) ? 0 : 1;
246 }
247
248 /* end of test_gnunet_helper_testbed.c */