tracking forwarded operations
[oweals/gnunet.git] / src / testbed / test_gnunet_helper_testbed.c
1 /*
2       This file is part of GNUnet
3       (C) 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 /**
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 GNUNET_SCHEDULER_TaskIdentifier abort_task;
62
63 /**
64  * Shutdown task identifier
65  */
66 static GNUNET_SCHEDULER_TaskIdentifier 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  * @param tc the task context
84  */
85 static void
86 do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
87 {
88   if (GNUNET_SCHEDULER_NO_TASK != abort_task)
89     GNUNET_SCHEDULER_cancel (abort_task);
90   GNUNET_HELPER_stop (helper);
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  * @param tc the task context
102  */
103 static void
104 do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
105 {
106   abort_task = GNUNET_SCHEDULER_NO_TASK;
107   LOG (GNUNET_ERROR_TYPE_WARNING, "Test timedout -- Aborting\n");
108   result = GNUNET_SYSERR;
109   if (NULL != shandle)
110     GNUNET_HELPER_send_cancel (shandle);
111   if (GNUNET_SCHEDULER_NO_TASK == shutdown_task)
112     shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
113 }
114
115
116 /**
117  * Continuation function.
118  *
119  * @param cls closure
120  * @param result GNUNET_OK on success,
121  *               GNUNET_NO if helper process died
122  *               GNUNET_SYSERR during GNUNET_HELPER_stop
123  */
124 static void
125 cont_cb (void *cls, int result)
126 {
127   shandle = NULL;
128   LOG (GNUNET_ERROR_TYPE_DEBUG, "Message sent\n");
129   GNUNET_assert (GNUNET_OK == result);
130 }
131
132
133 /**
134  * Functions with this signature are called whenever a
135  * complete message is received by the tokenizer.
136  *
137  * Do not call GNUNET_SERVER_mst_destroy in callback
138  *
139  * @param cls closure
140  * @param client identification of the client
141  * @param message the actual message
142  *
143  * @return GNUNET_OK on success, GNUNET_SYSERR to stop further processing
144  */
145 static int
146 mst_cb (void *cls, void *client, const struct GNUNET_MessageHeader *message)
147 {
148   const struct GNUNET_TESTBED_HelperReply *msg;
149   char *config;
150   uLongf config_size;
151   uLongf xconfig_size;
152
153   msg = (const struct GNUNET_TESTBED_HelperReply *) message;
154   config_size = 0;
155   xconfig_size = 0;
156   GNUNET_assert (sizeof (struct GNUNET_TESTBED_HelperReply) <
157                  ntohs (msg->header.size));
158   GNUNET_assert (GNUNET_MESSAGE_TYPE_TESTBED_HELPER_REPLY ==
159                  ntohs (msg->header.type));
160   config_size = (uLongf) ntohs (msg->config_size);
161   xconfig_size =
162       (uLongf) (ntohs (msg->header.size) -
163                 sizeof (struct GNUNET_TESTBED_HelperReply));
164   config = GNUNET_malloc (config_size);
165   GNUNET_assert (Z_OK ==
166                  uncompress ((Bytef *) config, &config_size,
167                              (const Bytef *) &msg[1], xconfig_size));
168   GNUNET_free (config);
169   if (GNUNET_SCHEDULER_NO_TASK == shutdown_task)
170     shutdown_task =
171         GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
172                                       (GNUNET_TIME_UNIT_SECONDS, 1),
173                                       &do_shutdown, NULL);
174   return GNUNET_OK;
175 }
176
177
178 /**
179  * Callback that will be called when the helper process dies. This is not called
180  * when the helper process is stoped using GNUNET_HELPER_stop()
181  *
182  * @param cls the closure from GNUNET_HELPER_start()
183  */
184 static void
185 exp_cb (void *cls)
186 {
187   helper = NULL;
188   result = GNUNET_SYSERR;
189 }
190
191
192 /**
193  * Main function that will be run.
194  *
195  * @param cls closure
196  * @param args remaining command-line arguments
197  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
198  * @param cfg configuration
199  */
200 static void
201 run (void *cls, char *const *args, const char *cfgfile,
202      const struct GNUNET_CONFIGURATION_Handle *cfg2)
203 {
204   static char *const binary_argv[] = {
205     "gnunet-helper-testbed",
206     NULL
207   };
208   const char *controller_name = "127.0.0.1";
209
210   helper =
211       GNUNET_HELPER_start (GNUNET_YES, "gnunet-helper-testbed", binary_argv,
212                            &mst_cb, &exp_cb, NULL);
213   GNUNET_assert (NULL != helper);
214   cfg = GNUNET_CONFIGURATION_dup (cfg2);
215   msg = GNUNET_TESTBED_create_helper_init_msg_ (controller_name, NULL, cfg);
216   shandle =
217       GNUNET_HELPER_send (helper, &msg->header, GNUNET_NO, &cont_cb, NULL);
218   GNUNET_assert (NULL != shandle);
219   abort_task =
220       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
221                                     (GNUNET_TIME_UNIT_MINUTES, 1), &do_abort,
222                                     NULL);
223 }
224
225
226 /**
227  * Main function
228  *
229  * @param argc the number of command line arguments
230  * @param argv command line arg array
231  * @return return code
232  */
233 int
234 main (int argc, char **argv)
235 {
236   struct GNUNET_GETOPT_CommandLineOption options[] = {
237     GNUNET_GETOPT_OPTION_END
238   };
239
240   result = GNUNET_OK;
241   if (GNUNET_OK !=
242       GNUNET_PROGRAM_run (argc, argv, "test_gnunet_helper_testbed",
243                           "Testcase for testing gnunet-helper-testbed.c",
244                           options, &run, NULL))
245     return 1;
246   return (GNUNET_OK == result) ? 0 : 1;
247 }
248
249 /* end of test_gnunet_helper_testbed.c */