aboutsummaryrefslogtreecommitdiff
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
parent0f87ae3787762ea32fb3d9580d13782cb2aacdd2 (diff)
downloadgnunet-f16a134a75db3cd13abdbc3fd3536000ed6b9c7f.tar.gz
gnunet-f16a134a75db3cd13abdbc3fd3536000ed6b9c7f.zip
merged 'gnunet-testing-run-service' into 'gnunet-testing'
-rw-r--r--src/testing/Makefile.am12
-rw-r--r--src/testing/gnunet-testing-run-service.c213
-rw-r--r--src/testing/gnunet-testing.c175
3 files changed, 169 insertions, 231 deletions
diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am
index f2355da5f..fb6bc091e 100644
--- a/src/testing/Makefile.am
+++ b/src/testing/Makefile.am
@@ -28,20 +28,8 @@ libgnunettesting_la_LDFLAGS = \
28 -version-info 2:0:1 28 -version-info 2:0:1
29 29
30bin_PROGRAMS = \ 30bin_PROGRAMS = \
31 gnunet-testing-run-service \
32 gnunet-testing 31 gnunet-testing
33 32
34
35gnunet_testing_run_service_SOURCES = \
36 gnunet-testing-run-service.c
37
38gnunet_testing_run_service_LDADD = \
39 $(top_builddir)/src/util/libgnunetutil.la \
40 $(top_builddir)/src/testing/libgnunettesting.la \
41 $(GN_LIBINTL)
42gnunet_testing_run_service_DEPENDENCIES = \
43 libgnunettesting.la
44
45gnunet_testing_SOURCES = \ 33gnunet_testing_SOURCES = \
46 gnunet-testing.c 34 gnunet-testing.c
47gnunet_testing_LDADD = \ 35gnunet_testing_LDADD = \
diff --git a/src/testing/gnunet-testing-run-service.c b/src/testing/gnunet-testing-run-service.c
deleted file mode 100644
index 24b85a7e8..000000000
--- a/src/testing/gnunet-testing-run-service.c
+++ /dev/null
@@ -1,213 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2004, 2005, 2006, 2007, 2009 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/**
23 * @file testing/gnunet-testing-run-service.c
24 * @brief tool to start a service for testing
25 * @author Florian Dold
26 *
27 * Start a peer, running only the service specified on the command line.
28 * Outputs the path to the temporary configuration file to stdout.
29 *
30 * The peer will run until this program is killed,
31 * or stdin is closed. When reading the character 'r' from stdin,
32 * the running service is restarted with the same configuration.
33 *
34 * This executable is intended to be used by gnunet-java, in order to reliably
35 * start and stop services for test cases.
36 */
37#include "platform.h"
38#include "gnunet_util_lib.h"
39#include "gnunet_testing_lib.h"
40
41#define LOG(kind,...) \
42 GNUNET_log_from (kind, "gnunet-testing", __VA_ARGS__)
43
44
45/**
46 * File handle to STDIN, for reading restart/quit commands.
47 */
48static struct GNUNET_DISK_FileHandle *fh;
49
50/**
51 * FIXME
52 */
53static char *tmpfilename;
54
55/**
56 * FIXME
57 */
58static GNUNET_SCHEDULER_TaskIdentifier tid;
59
60/**
61 * FIXME
62 */
63static struct GNUNET_TESTING_Peer *my_peer;
64
65
66
67
68/**
69 * Cleanup called by signal handlers and when stdin is closed.
70 * Removes the temporary file.
71 *
72 * @param cls unused
73 * @param tc scheduler context
74 */
75static void
76cleanup (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
77{
78 if (NULL != tmpfilename)
79 {
80 if (0 != UNLINK (tmpfilename))
81 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", tmpfilename);
82 }
83 if (GNUNET_SCHEDULER_NO_TASK != tid)
84 {
85 GNUNET_SCHEDULER_cancel (tid);
86 tid = GNUNET_SCHEDULER_NO_TASK;
87 }
88 if (NULL != fh)
89 {
90 GNUNET_DISK_file_close (fh);
91 fh = NULL;
92 }
93}
94
95
96/**
97 * Called whenever we can read stdin non-blocking
98 *
99 * @param cls unused
100 * @param tc scheduler context
101 */
102static void
103stdin_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
104{
105 int c;
106
107 tid = GNUNET_SCHEDULER_NO_TASK;
108 if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
109 return;
110 GNUNET_assert (0 != (GNUNET_SCHEDULER_REASON_READ_READY & tc->reason));
111 c = getchar ();
112 switch (c)
113 {
114 case EOF:
115 case 'q':
116 GNUNET_SCHEDULER_shutdown ();
117 return;
118 case 'r':
119 if (GNUNET_OK != GNUNET_TESTING_peer_stop (my_peer))
120 LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to stop the peer\n");
121 if (GNUNET_OK != GNUNET_TESTING_peer_start (my_peer))
122 LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to start the peer\n");
123 printf ("restarted\n");
124 fflush (stdout);
125 break;
126 case '\n':
127 case '\r':
128 /* ignore whitespace */
129 break;
130 default:
131 fprintf (stderr, _("Unknown command, use 'q' to quit or 'r' to restart peer\n"));
132 break;
133 }
134 tid = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, fh,
135 &stdin_cb, NULL);
136}
137
138
139/**
140 * Main function called by the testing library.
141 * Executed inside a running scheduler.
142 *
143 * @param cls unused
144 * @param cfg configuration of the peer that was started
145 * @param peer handle to the peer
146 */
147static void
148testing_main (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg,
149 struct GNUNET_TESTING_Peer *peer)
150{
151 my_peer = peer;
152 if (NULL == (tmpfilename = GNUNET_DISK_mktemp ("gnunet-testing")))
153 {
154 GNUNET_break (0);
155 GNUNET_SCHEDULER_shutdown ();
156 return;
157 }
158 if (GNUNET_SYSERR ==
159 GNUNET_CONFIGURATION_write ((struct GNUNET_CONFIGURATION_Handle *) cfg,
160 tmpfilename))
161 {
162 GNUNET_break (0);
163 return;
164 }
165 printf("ok\n%s\n", tmpfilename);
166 fflush(stdout);
167 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, NULL);
168 fh = GNUNET_DISK_get_handle_from_native (stdin);
169 tid = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, fh,
170 &stdin_cb, NULL);
171}
172
173
174/**
175 * The main function.
176 *
177 * @param argc number of arguments from the command line
178 * @param argv command line arguments
179 * @return 0 ok, 1 on error
180 */
181int
182main (int argc, char *const *argv)
183{
184 static char *cfg_name;
185 static char *srv_name;
186 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
187 {'c', "config", "FILENAME",
188 gettext_noop ("name of the template configuration file to use (optional)"), GNUNET_NO,
189 &GNUNET_GETOPT_set_string, &cfg_name},
190 {'s', "service", "SERVICE",
191 gettext_noop ("name of the service to run"), GNUNET_YES,
192 &GNUNET_GETOPT_set_string, &srv_name},
193 GNUNET_GETOPT_OPTION_HELP ("tool to start a service for testing"),
194 GNUNET_GETOPT_OPTION_END
195 };
196 int ret;
197
198 if (GNUNET_SYSERR ==
199 GNUNET_GETOPT_run ("gnunet-testing-run-service", options, argc, argv))
200 return 1;
201 ret = GNUNET_TESTING_service_run ("gnunet_service_test", srv_name,
202 cfg_name, &testing_main, NULL);
203 if (0 != ret)
204 {
205 printf ("error\n");
206 }
207 else
208 {
209 printf ("bye\n");
210 }
211 return ret;
212}
213
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}