aboutsummaryrefslogtreecommitdiff
path: root/src/testing/gnunet-testing.c
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2013-08-27 14:37:38 +0000
committerFlorian Dold <florian.dold@gmail.com>2013-08-27 14:37:38 +0000
commitf16a134a75db3cd13abdbc3fd3536000ed6b9c7f (patch)
treed74b4981732112968d17ac32e10e34a95641b2a4 /src/testing/gnunet-testing.c
parent0f87ae3787762ea32fb3d9580d13782cb2aacdd2 (diff)
downloadgnunet-f16a134a75db3cd13abdbc3fd3536000ed6b9c7f.tar.gz
gnunet-f16a134a75db3cd13abdbc3fd3536000ed6b9c7f.zip
merged 'gnunet-testing-run-service' into 'gnunet-testing'
Diffstat (limited to 'src/testing/gnunet-testing.c')
-rw-r--r--src/testing/gnunet-testing.c175
1 files changed, 169 insertions, 6 deletions
diff --git a/src/testing/gnunet-testing.c b/src/testing/gnunet-testing.c
index b3d3ac268..8c5da490e 100644
--- a/src/testing/gnunet-testing.c
+++ b/src/testing/gnunet-testing.c
@@ -28,19 +28,62 @@
28#include "gnunet_testing_lib.h" 28#include "gnunet_testing_lib.h"
29 29
30 30
31#define LOG(kind,...) \
32 GNUNET_log_from (kind, "gnunet-testing", __VA_ARGS__)
33
34
31/** 35/**
32 * Final status code. 36 * Final status code.
33 */ 37 */
34static int ret; 38static int ret;
35 39
40/**
41 * Filename of the hostkey file we should write,
42 * null if we should not write a hostkey file.
43 */
36static char *create_hostkey; 44static char *create_hostkey;
37 45
46/**
47 * Non-zero if we should create config files.
48 */
38static int create_cfg; 49static int create_cfg;
39 50
51/**
52 * Number of config files to create.
53 */
40static unsigned int create_no; 54static unsigned int create_no;
41 55
56/**
57 * Filename of the config template to be written.
58 */
42static char *create_cfg_template; 59static char *create_cfg_template;
43 60
61/**
62 * Service we are supposed to run.
63 */
64static char *run_service_name;
65
66/**
67 * File handle to STDIN, for reading restart/quit commands.
68 */
69static struct GNUNET_DISK_FileHandle *fh;
70
71/**
72 * Temporary filename, used with '-r' to write the configuration to.
73 */
74static char *tmpfilename;
75
76/**
77 * Task identifier of the task that waits for stdin.
78 */
79static GNUNET_SCHEDULER_TaskIdentifier tid;
80
81/**
82 * Peer started for '-r'.
83 */
84static struct GNUNET_TESTING_Peer *my_peer;
85
86
44 87
45static int 88static int
46create_unique_cfgs (const char * template, const unsigned int no) 89create_unique_cfgs (const char * template, const unsigned int no)
@@ -150,7 +193,114 @@ create_hostkeys (const unsigned int no)
150 193
151 194
152/** 195/**
153 * Main function that will be run by the scheduler. 196 * Cleanup called by signal handlers and when stdin is closed.
197 * Removes the temporary file.
198 *
199 * @param cls unused
200 * @param tc scheduler context
201 */
202static void
203cleanup (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
204{
205 if (NULL != tmpfilename)
206 {
207 if (0 != UNLINK (tmpfilename))
208 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", tmpfilename);
209 }
210 if (GNUNET_SCHEDULER_NO_TASK != tid)
211 {
212 GNUNET_SCHEDULER_cancel (tid);
213 tid = GNUNET_SCHEDULER_NO_TASK;
214 }
215 if (NULL != fh)
216 {
217 GNUNET_DISK_file_close (fh);
218 fh = NULL;
219 }
220}
221
222
223/**
224 * Called whenever we can read stdin non-blocking
225 *
226 * @param cls unused
227 * @param tc scheduler context
228 */
229static void
230stdin_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
231{
232 int c;
233
234 tid = GNUNET_SCHEDULER_NO_TASK;
235 if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
236 return;
237 GNUNET_assert (0 != (GNUNET_SCHEDULER_REASON_READ_READY & tc->reason));
238 c = getchar ();
239 switch (c)
240 {
241 case EOF:
242 case 'q':
243 GNUNET_SCHEDULER_shutdown ();
244 return;
245 case 'r':
246 if (GNUNET_OK != GNUNET_TESTING_peer_stop (my_peer))
247 LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to stop the peer\n");
248 if (GNUNET_OK != GNUNET_TESTING_peer_start (my_peer))
249 LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to start the peer\n");
250 printf ("restarted\n");
251 fflush (stdout);
252 break;
253 case '\n':
254 case '\r':
255 /* ignore whitespace */
256 break;
257 default:
258 fprintf (stderr, _("Unknown command, use 'q' to quit or 'r' to restart peer\n"));
259 break;
260 }
261 tid = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, fh,
262 &stdin_cb, NULL);
263}
264
265
266/**
267 * Main function called by the testing library.
268 * Executed inside a running scheduler.
269 *
270 * @param cls unused
271 * @param cfg configuration of the peer that was started
272 * @param peer handle to the peer
273 */
274static void
275testing_main (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg,
276 struct GNUNET_TESTING_Peer *peer)
277{
278 my_peer = peer;
279 if (NULL == (tmpfilename = GNUNET_DISK_mktemp ("gnunet-testing")))
280 {
281 GNUNET_break (0);
282 GNUNET_SCHEDULER_shutdown ();
283 return;
284 }
285 if (GNUNET_SYSERR ==
286 GNUNET_CONFIGURATION_write ((struct GNUNET_CONFIGURATION_Handle *) cfg,
287 tmpfilename))
288 {
289 GNUNET_break (0);
290 return;
291 }
292 printf("ok\n%s\n", tmpfilename);
293 fflush(stdout);
294 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, NULL);
295 fh = GNUNET_DISK_get_handle_from_native (stdin);
296 tid = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, fh,
297 &stdin_cb, NULL);
298}
299
300
301
302/**
303 * Main function that will be running without scheduler.
154 * 304 *
155 * @param cls closure 305 * @param cls closure
156 * @param args remaining command-line arguments 306 * @param args remaining command-line arguments
@@ -158,10 +308,17 @@ create_hostkeys (const unsigned int no)
158 * @param cfg configuration 308 * @param cfg configuration
159 */ 309 */
160static void 310static void
161run (void *cls, char *const *args, const char *cfgfile, 311run_no_scheduler (void *cls, char *const *args, const char *cfgfile,
162 const struct GNUNET_CONFIGURATION_Handle *cfg) 312 const struct GNUNET_CONFIGURATION_Handle *cfg)
163{ 313{
164 /* main code here */ 314 if (NULL != run_service_name)
315 {
316 printf ("testing run\n");
317 ret = GNUNET_TESTING_service_run ("gnunet_service_test", run_service_name,
318 cfgfile, &testing_main, NULL);
319 return;
320 }
321
165 if (GNUNET_YES == create_cfg) 322 if (GNUNET_YES == create_cfg)
166 { 323 {
167 if (create_no > 0) 324 if (create_no > 0)
@@ -204,15 +361,21 @@ main (int argc, char *const *argv)
204 GNUNET_YES, &GNUNET_GETOPT_set_uint, &create_no}, 361 GNUNET_YES, &GNUNET_GETOPT_set_uint, &create_no},
205 {'t', "template", "FILENAME", gettext_noop ("configuration template"), 362 {'t', "template", "FILENAME", gettext_noop ("configuration template"),
206 GNUNET_YES, &GNUNET_GETOPT_set_string, &create_cfg_template}, 363 GNUNET_YES, &GNUNET_GETOPT_set_string, &create_cfg_template},
364 {'r', "run", "SERVICE", gettext_noop ("run the given service, wait on stdin for 'r' (restart) or 'q' (quit)"),
365 GNUNET_YES, &GNUNET_GETOPT_set_string, &run_service_name},
207 GNUNET_GETOPT_OPTION_END 366 GNUNET_GETOPT_OPTION_END
208 }; 367 };
209 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) 368 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
210 return 2; 369 return 2;
211 370
371 /* Run without scheduler, because we may want to call
372 * GNUNET_TESTING_service_run, which starts the scheduler on its own.
373 * Furthermore, the other functionality currently does not require the scheduler, too,
374 * but beware when extending gnunet-testing. */
212 ret = (GNUNET_OK == 375 ret = (GNUNET_OK ==
213 GNUNET_PROGRAM_run (argc, argv, "gnunet-testing", 376 GNUNET_PROGRAM_run2 (argc, argv, "gnunet-testing",
214 gettext_noop ("Command line tool to access the testing library"), options, &run, 377 gettext_noop ("Command line tool to access the testing library"), options, &run_no_scheduler,
215 NULL)) ? ret : 1; 378 NULL, GNUNET_YES)) ? ret : 1;
216 GNUNET_free ((void*) argv); 379 GNUNET_free ((void*) argv);
217 return ret; 380 return ret;
218} 381}