aboutsummaryrefslogtreecommitdiff
path: root/src/testing
diff options
context:
space:
mode:
authort3sserakt <t3ss@posteo.de>2021-08-17 19:57:12 +0200
committert3sserakt <t3ss@posteo.de>2021-08-17 19:57:12 +0200
commit32a8c505c1fa27bb43c4e7c8d288566d51417f56 (patch)
tree0328fe50b6a099b5020fe6d1e01cbd6b96ecd18a /src/testing
parent1e063cd73452396778cf00127346b9b08a922317 (diff)
downloadgnunet-32a8c505c1fa27bb43c4e7c8d288566d51417f56.tar.gz
gnunet-32a8c505c1fa27bb43c4e7c8d288566d51417f56.zip
- moved test code from testbed to testing
Diffstat (limited to 'src/testing')
-rw-r--r--src/testing/Makefile.am41
-rw-r--r--src/testing/gnunet-cmds-helper.c662
-rw-r--r--src/testing/test_testing_api_cmd_netjail.c79
-rw-r--r--src/testing/test_testing_plugin_testcmd.c116
-rw-r--r--src/testing/testing_api_cmd_block_until_all_peers_started.c128
-rw-r--r--src/testing/testing_api_cmd_local_test_finished.c131
-rw-r--r--src/testing/testing_api_cmd_netjail_start.c217
-rw-r--r--src/testing/testing_api_cmd_netjail_start_testsystem.c541
-rw-r--r--src/testing/testing_api_cmd_netjail_stop.c215
-rw-r--r--src/testing/testing_api_cmd_netjail_stop_testsystem.c141
-rw-r--r--src/testing/testing_api_cmd_send_peer_ready.c5
-rw-r--r--src/testing/testing_cmds.h90
12 files changed, 2363 insertions, 3 deletions
diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am
index 8b28e6e23..15469a310 100644
--- a/src/testing/Makefile.am
+++ b/src/testing/Makefile.am
@@ -11,10 +11,43 @@ pkgcfgdir= $(pkgdatadir)/config.d/
11dist_pkgcfg_DATA = \ 11dist_pkgcfg_DATA = \
12 testing.conf 12 testing.conf
13 13
14libexec_PROGRAMS = \
15 gnunet-cmds-helper
16
17plugindir = $(libdir)/gnunet
18
19plugin_LTLIBRARIES = \
20 libgnunet_test_testing_plugin_testcmd.la
21
14lib_LTLIBRARIES = \ 22lib_LTLIBRARIES = \
15 libgnunettesting.la 23 libgnunettesting.la
16 24
25gnunet_cmds_helper_SOURCES = \
26 gnunet-cmds-helper.c
27gnunet_cmds_helper_LDADD = $(XLIB) \
28 $(top_builddir)/src/util/libgnunetutil.la \
29 libgnunettesting.la \
30 $(LTLIBINTL) $(Z_LIBS)
31
32libgnunet_test_testing_plugin_testcmd_la_SOURCES = \
33 test_testing_plugin_testcmd.c
34libgnunet_test_testing_plugin_testcmd_la_LIBADD = \
35 $(top_builddir)/src/util/libgnunetutil.la \
36 $(top_builddir)/src/arm/libgnunetarm.la \
37 libgnunettesting.la \
38 $(top_builddir)/src/statistics/libgnunetstatistics.la \
39 $(LTLIBINTL)
40libgnunet_test_testing_plugin_testcmd_la_LDFLAGS = \
41 $(GN_PLUGIN_LDFLAGS)
42
17libgnunettesting_la_SOURCES = \ 43libgnunettesting_la_SOURCES = \
44 testing_api_cmd_local_test_finished.c \
45 testing_api_cmd_send_peer_ready.c \
46 testing_api_cmd_block_until_all_peers_started.c \
47 testing_api_cmd_netjail_start.c \
48 testing_api_cmd_netjail_start_testsystem.c \
49 testing_api_cmd_netjail_stop_testsystem.c \
50 testing_api_cmd_netjail_stop.c \
18 testing.c testing.h \ 51 testing.c testing.h \
19 testing_api_cmd_system_create.c \ 52 testing_api_cmd_system_create.c \
20 testing_api_cmd_batch.c \ 53 testing_api_cmd_batch.c \
@@ -56,6 +89,7 @@ list_keys_LDADD = \
56 89
57 90
58check_PROGRAMS = \ 91check_PROGRAMS = \
92 test_testing_api_cmd_netjail \
59 test_testing_hello_world \ 93 test_testing_hello_world \
60 test_testing_portreservation \ 94 test_testing_portreservation \
61 test_testing_servicestartup \ 95 test_testing_servicestartup \
@@ -66,6 +100,7 @@ check_PROGRAMS = \
66if ENABLE_TEST_RUN 100if ENABLE_TEST_RUN
67AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; 101AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME;
68TESTS = \ 102TESTS = \
103 test_testing_api_cmd_netjail \
69 test_testing_hello_world \ 104 test_testing_hello_world \
70 test_testing_portreservation \ 105 test_testing_portreservation \
71 test_testing_peerstartup \ 106 test_testing_peerstartup \
@@ -73,6 +108,12 @@ TESTS = \
73 test_testing_servicestartup 108 test_testing_servicestartup
74endif 109endif
75 110
111test_testing_api_cmd_netjail_SOURCES = \
112 test_testing_api_cmd_netjail.c
113test_testing_api_cmd_netjail_LDADD = \
114 libgnunettesting.la \
115 $(top_builddir)/src/util/libgnunetutil.la
116
76test_testing_hello_world_SOURCES = \ 117test_testing_hello_world_SOURCES = \
77 test_testing_hello_world.c 118 test_testing_hello_world.c
78test_testing_hello_world_LDADD = \ 119test_testing_hello_world_LDADD = \
diff --git a/src/testing/gnunet-cmds-helper.c b/src/testing/gnunet-cmds-helper.c
new file mode 100644
index 000000000..d9fcf3541
--- /dev/null
+++ b/src/testing/gnunet-cmds-helper.c
@@ -0,0 +1,662 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2008--2013, 2016 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file testbed/gnunet-cmds-helper.c
23 * @brief Helper binary that is started from a remote interpreter loop to start
24 * a local interpreter loop.
25 *
26 * This helper monitors for three termination events. They are: (1)The
27 * stdin of the helper is closed for reading; (2)the helper received
28 * SIGTERM/SIGINT; (3)the local loop crashed. In case of events 1 and 2
29 * the helper kills the interpreter loop. When the interpreter loop
30 * crashed (event 3), the helper should send a SIGTERM to its own process
31 * group; this behaviour will help terminate any child processes the loop
32 * has started and prevents them from leaking and running forever.
33 *
34 * @author t3sserakt
35 * @author Sree Harsha Totakura <sreeharsha@totakura.in>
36 */
37
38
39#include "platform.h"
40#include "gnunet_util_lib.h"
41#include "gnunet_testing_lib.h"
42#include "gnunet_testing_ng_lib.h"
43#include "testing_cmds.h"
44#include "gnunet_testing_plugin.h"
45#include <zlib.h>
46
47
48/**
49 * Generic logging shortcut
50 */
51#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
52
53/**
54 * Debug logging shorthand
55 */
56#define LOG_DEBUG(...) LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
57
58#define NODE_BASE_IP "192.168.15."
59
60#define ROUTER_BASE_IP "92.68.150."
61
62/**
63 * Handle for a plugin.
64 */
65struct Plugin
66{
67 /**
68 * Name of the shared library.
69 */
70 char *library_name;
71
72 /**
73 * Plugin API.
74 */
75 struct GNUNET_TESTING_PluginFunctions *api;
76
77 char *node_ip;
78
79 char *plugin_name;
80
81 char *global_n;
82
83 char *local_m;
84
85 char *n;
86
87 char *m;
88};
89
90struct NodeIdentifier
91{
92 char *n;
93
94 char *m;
95
96 char *global_n;
97
98 char *local_m;
99};
100
101/**
102 * Context for a single write on a chunk of memory
103 */
104struct WriteContext
105{
106 /**
107 * The data to write
108 */
109 void *data;
110
111 /**
112 * The length of the data
113 */
114 size_t length;
115
116 /**
117 * The current position from where the write operation should begin
118 */
119 size_t pos;
120};
121
122struct Plugin *plugin;
123
124/**
125 * The process handle to the testbed service
126
127static struct GNUNET_OS_Process *cmd_binary_process;*/
128
129/**
130 * Handle to the testing system
131 */
132static struct GNUNET_TESTING_System *test_system;
133
134/**
135 * Our message stream tokenizer
136 */
137struct GNUNET_MessageStreamTokenizer *tokenizer;
138
139/**
140 * Disk handle from stdin
141 */
142static struct GNUNET_DISK_FileHandle *stdin_fd;
143
144/**
145 * Disk handle for stdout
146 */
147static struct GNUNET_DISK_FileHandle *stdout_fd;
148
149/**
150 * Pipe used to communicate shutdown via signal.
151 */
152static struct GNUNET_DISK_PipeHandle *sigpipe;
153
154/**
155 * Task identifier for the read task
156 */
157static struct GNUNET_SCHEDULER_Task *read_task_id;
158
159/**
160 * Task identifier for the write task
161 */
162static struct GNUNET_SCHEDULER_Task *write_task_id;
163
164/**
165 * Task to kill the child
166 */
167static struct GNUNET_SCHEDULER_Task *child_death_task_id;
168
169/**
170 * Are we done reading messages from stdin?
171 */
172static int done_reading;
173
174/**
175 * Result to return in case we fail
176 */
177static int status;
178
179
180/**
181 * Task to shut down cleanly
182 *
183 * @param cls NULL
184 */
185static void
186shutdown_task (void *cls)
187{
188
189 LOG_DEBUG ("Shutting down.\n");
190 LOG (GNUNET_ERROR_TYPE_ERROR,
191 "Shutting down tokenizer!\n");
192
193 if (NULL != read_task_id)
194 {
195 GNUNET_SCHEDULER_cancel (read_task_id);
196 read_task_id = NULL;
197 }
198 if (NULL != write_task_id)
199 {
200 struct WriteContext *wc;
201
202 wc = GNUNET_SCHEDULER_cancel (write_task_id);
203 write_task_id = NULL;
204 GNUNET_free (wc->data);
205 GNUNET_free (wc);
206 }
207 if (NULL != child_death_task_id)
208 {
209 GNUNET_SCHEDULER_cancel (child_death_task_id);
210 child_death_task_id = NULL;
211 }
212 if (NULL != stdin_fd)
213 (void) GNUNET_DISK_file_close (stdin_fd);
214 if (NULL != stdout_fd)
215 (void) GNUNET_DISK_file_close (stdout_fd);
216 GNUNET_MST_destroy (tokenizer);
217 tokenizer = NULL;
218
219 if (NULL != test_system)
220 {
221 GNUNET_TESTING_system_destroy (test_system, GNUNET_YES);
222 test_system = NULL;
223 }
224}
225
226
227/**
228 * Task to write to the standard out
229 *
230 * @param cls the WriteContext
231 */
232static void
233write_task (void *cls)
234{
235 struct WriteContext *wc = cls;
236 ssize_t bytes_wrote;
237
238 LOG (GNUNET_ERROR_TYPE_ERROR,
239 "Writing data!\n");
240
241 GNUNET_assert (NULL != wc);
242 write_task_id = NULL;
243 bytes_wrote = GNUNET_DISK_file_write (stdout_fd,
244 wc->data + wc->pos,
245 wc->length - wc->pos);
246 if (GNUNET_SYSERR == bytes_wrote)
247 {
248 LOG (GNUNET_ERROR_TYPE_WARNING,
249 "Cannot reply back successful initialization\n");
250 GNUNET_free (wc->data);
251 GNUNET_free (wc);
252 return;
253 }
254 wc->pos += bytes_wrote;
255 if (wc->pos == wc->length)
256 {
257 GNUNET_free (wc->data);
258 GNUNET_free (wc);
259 LOG (GNUNET_ERROR_TYPE_ERROR,
260 "Written successfully!\n");
261 return;
262 }
263 LOG (GNUNET_ERROR_TYPE_ERROR,
264 "Written data!\n");
265 write_task_id = GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
266 stdout_fd,
267 &write_task,
268 wc);
269}
270
271
272/**
273 * Task triggered whenever we receive a SIGCHLD (child
274 * process died).
275 *
276 * @param cls closure, NULL if we need to self-restart
277 */
278/*static void
279child_death_task (void *cls)
280{
281 const struct GNUNET_DISK_FileHandle *pr;
282 char c[16];
283
284 pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ);
285 child_death_task_id = NULL;
286 // consume the signal
287 GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof(c)));
288 LOG_DEBUG ("Got SIGCHLD\n");
289
290 LOG_DEBUG ("Child hasn't died. Resuming to monitor its status\n");
291 child_death_task_id =
292 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
293 pr,
294 &child_death_task,
295 NULL);
296}*/
297
298
299static void
300write_message (struct GNUNET_MessageHeader *message, size_t msg_length)
301{
302 struct WriteContext *wc;
303
304 LOG (GNUNET_ERROR_TYPE_ERROR,
305 "enter write_message!\n");
306 wc = GNUNET_new (struct WriteContext);
307 wc->length = msg_length;
308 wc->data = message;
309 write_task_id = GNUNET_SCHEDULER_add_write_file (
310 GNUNET_TIME_UNIT_FOREVER_REL,
311 stdout_fd,
312 &write_task,
313 wc);
314 LOG (GNUNET_ERROR_TYPE_ERROR,
315 "leave write_message!\n");
316}
317
318
319/**
320 * Function to run the test cases.
321 *
322 * @param cls plugin to use.
323 *
324 */
325/*static void
326run_plugin (void *cls)
327{
328 struct Plugin *plugin = cls;
329 char *router_ip;
330 char *node_ip;
331
332 router_ip = GNUNET_malloc (strlen (ROUTER_BASE_IP) + strlen (plugin->m) + 1);
333 strcpy (router_ip, ROUTER_BASE_IP);
334 strcat (router_ip, plugin->m);
335
336 node_ip = GNUNET_malloc (strlen (NODE_BASE_IP) + strlen (plugin->n) + 1);
337 strcat (node_ip, NODE_BASE_IP);
338 strcat (node_ip, plugin->n);
339
340 plugin->api->start_testcase (&write_message, router_ip, node_ip);
341
342}*/
343
344
345/**
346 * Functions with this signature are called whenever a
347 * complete message is received by the tokenizer.
348 *
349 * Do not call #GNUNET_mst_destroy() in this callback
350 *
351 * @param cls identification of the client
352 * @param message the actual message
353 * @return #GNUNET_OK on success,
354 * #GNUNET_NO to stop further processing (no error)
355 * #GNUNET_SYSERR to stop further processing with error
356 */
357static int
358tokenizer_cb (void *cls, const struct GNUNET_MessageHeader *message)
359{
360 struct NodeIdentifier *ni = cls;
361 const struct GNUNET_CMDS_HelperInit *msg;
362 struct GNUNET_CMDS_HelperReply *reply;
363 char *binary;
364 char *plugin_name;
365 size_t plugin_name_size;
366 uint16_t msize;
367 size_t msg_length;
368 char *router_ip;
369 char *node_ip;
370
371 LOG (GNUNET_ERROR_TYPE_ERROR,
372 "tokenizer \n");
373
374 msize = ntohs (message->size);
375 if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT == ntohs (message->type))
376 {
377 msg = (const struct GNUNET_CMDS_HelperInit *) message;
378 plugin_name_size = ntohs (msg->plugin_name_size);
379 if ((sizeof(struct GNUNET_CMDS_HelperInit) + plugin_name_size) > msize)
380 {
381 GNUNET_break (0);
382 LOG (GNUNET_ERROR_TYPE_WARNING,
383 "Received unexpected message -- exiting\n");
384 goto error;
385 }
386 plugin_name = GNUNET_malloc (plugin_name_size + 1);
387 GNUNET_strlcpy (plugin_name,
388 ((char *) &msg[1]),
389 plugin_name_size + 1);
390
391 binary = GNUNET_OS_get_libexec_binary_path ("gnunet-cmd");
392
393 LOG (GNUNET_ERROR_TYPE_ERROR,
394 "plugin_name: %s \n",
395 plugin_name);
396
397 // cmd_binary_process = GNUNET_OS_start_process (
398 /*GNUNET_OS_INHERIT_STD_ERR verbose? ,
399 NULL,
400 NULL,
401 NULL,
402 binary,
403 plugin_name,
404 ni->global_n,
405 ni->local_m,
406 ni->n,
407 ni->m,
408 NULL);*/
409
410 plugin = GNUNET_new (struct Plugin);
411 plugin->api = GNUNET_PLUGIN_load (plugin_name,
412 NULL);
413 plugin->library_name = GNUNET_strdup (basename (plugin_name));
414
415 plugin->global_n = ni->global_n;
416 plugin->local_m = ni->local_m;
417 plugin->n = ni->n;
418 plugin->m = ni->m;
419
420 router_ip = GNUNET_malloc (strlen (ROUTER_BASE_IP) + strlen (plugin->m)
421 + 1);
422 strcpy (router_ip, ROUTER_BASE_IP);
423 strcat (router_ip, plugin->m);
424
425 node_ip = GNUNET_malloc (strlen (NODE_BASE_IP) + strlen (plugin->n) + 1);
426 strcat (node_ip, NODE_BASE_IP);
427 strcat (node_ip, plugin->n);
428
429 plugin->api->start_testcase (&write_message, router_ip, node_ip, plugin->m,
430 plugin->n, plugin->local_m);
431
432 LOG (GNUNET_ERROR_TYPE_ERROR,
433 "We got here!\n");
434
435 /*if (NULL == cmd_binary_process)
436 {
437 LOG (GNUNET_ERROR_TYPE_ERROR,
438 "Starting plugin failed!\n");
439 return GNUNET_SYSERR;
440 }*/
441
442 LOG (GNUNET_ERROR_TYPE_ERROR,
443 "We got here 2!\n");
444
445 LOG (GNUNET_ERROR_TYPE_ERROR,
446 "global_n: %s local_n: %s n: %s m: %s.\n",
447 ni->global_n,
448 ni->local_m,
449 ni->n,
450 ni->m);
451
452 LOG (GNUNET_ERROR_TYPE_ERROR,
453 "We got here 3!\n");
454
455 GNUNET_free (binary);
456
457 // done_reading = GNUNET_YES;
458
459 msg_length = sizeof(struct GNUNET_CMDS_HelperReply);
460 reply = GNUNET_new (struct GNUNET_CMDS_HelperReply);
461 reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY);
462 reply->header.size = htons ((uint16_t) msg_length);
463
464 LOG (GNUNET_ERROR_TYPE_ERROR,
465 "We got here 4!\n");
466
467 write_message ((struct GNUNET_MessageHeader *) reply, msg_length);
468
469 LOG (GNUNET_ERROR_TYPE_ERROR,
470 "We got here 5!\n");
471
472 /*child_death_task_id = GNUNET_SCHEDULER_add_read_file (
473 GNUNET_TIME_UNIT_FOREVER_REL,
474 GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ),
475 &child_death_task,
476 NULL);*/
477 return GNUNET_OK;
478 }
479 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED == ntohs (
480 message->type))
481 {
482 plugin->api->all_peers_started ();
483 return GNUNET_OK;
484 }
485 else
486 {
487 LOG (GNUNET_ERROR_TYPE_WARNING, "Received unexpected message -- exiting\n");
488 goto error;
489 }
490
491
492 error:
493 status = GNUNET_SYSERR;
494 LOG (GNUNET_ERROR_TYPE_ERROR,
495 "tokenizer shutting down!\n");
496 GNUNET_SCHEDULER_shutdown ();
497 return GNUNET_SYSERR;
498}
499
500
501/**
502 * Task to read from stdin
503 *
504 * @param cls NULL
505 */
506static void
507read_task (void *cls)
508{
509 char buf[GNUNET_MAX_MESSAGE_SIZE];
510 ssize_t sread;
511
512 read_task_id = NULL;
513 sread = GNUNET_DISK_file_read (stdin_fd, buf, sizeof(buf));
514 if ((GNUNET_SYSERR == sread) || (0 == sread))
515 {
516 LOG_DEBUG ("STDIN closed\n");
517 LOG (GNUNET_ERROR_TYPE_ERROR,
518 "tokenizer shutting down during reading!\n");
519 GNUNET_SCHEDULER_shutdown ();
520 return;
521 }
522 if (GNUNET_YES == done_reading)
523 {
524 /* didn't expect any more data! */
525 GNUNET_break_op (0);
526 LOG (GNUNET_ERROR_TYPE_ERROR,
527 "tokenizer shutting down during reading, didn't expect any more data!\n");
528 GNUNET_SCHEDULER_shutdown ();
529 return;
530 }
531 LOG_DEBUG ("Read %u bytes\n", (unsigned int) sread);
532 LOG (GNUNET_ERROR_TYPE_ERROR,
533 "Read %u bytes\n", (unsigned int) sread);
534 /* FIXME: could introduce a GNUNET_MST_read2 to read
535 directly from 'stdin_fd' and save a memcpy() here */
536 if (GNUNET_OK !=
537 GNUNET_MST_from_buffer (tokenizer, buf, sread, GNUNET_NO, GNUNET_NO))
538 {
539 GNUNET_break (0);
540 LOG (GNUNET_ERROR_TYPE_ERROR,
541 "tokenizer shutting down during reading, writing to buffer failed!\n");
542 GNUNET_SCHEDULER_shutdown ();
543 return;
544 }
545 read_task_id /* No timeout while reading */
546 = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
547 stdin_fd,
548 &read_task,
549 NULL);
550}
551
552
553/**
554 * Main function that will be run.
555 *
556 * @param cls closure
557 * @param args remaining command-line arguments
558 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
559 * @param cfg configuration
560 */
561static void
562run (void *cls,
563 char *const *args,
564 const char *cfgfile,
565 const struct GNUNET_CONFIGURATION_Handle *cfg)
566{
567 struct NodeIdentifier *ni = cls;
568
569 LOG_DEBUG ("Starting interpreter loop helper...\n");
570
571 tokenizer = GNUNET_MST_create (&tokenizer_cb, ni);
572 stdin_fd = GNUNET_DISK_get_handle_from_native (stdin);
573 stdout_fd = GNUNET_DISK_get_handle_from_native (stdout);
574 read_task_id = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
575 stdin_fd,
576 &read_task,
577 NULL);
578 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
579}
580
581
582/**
583 * Signal handler called for SIGCHLD.
584 */
585static void
586sighandler_child_death ()
587{
588 static char c;
589 int old_errno; /* back-up errno */
590
591 old_errno = errno;
592 GNUNET_break (
593 1 ==
594 GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle (sigpipe,
595 GNUNET_DISK_PIPE_END_WRITE),
596 &c,
597 sizeof(c)));
598 errno = old_errno;
599}
600
601
602/**
603 * Main function
604 *
605 * @param argc the number of command line arguments
606 * @param argv command line arg array
607 * @return return code
608 */
609int
610main (int argc, char **argv)
611{
612 struct NodeIdentifier *ni;
613 struct GNUNET_SIGNAL_Context *shc_chld;
614 struct GNUNET_GETOPT_CommandLineOption options[] =
615 { GNUNET_GETOPT_OPTION_END };
616 int ret;
617
618 GNUNET_log_setup ("gnunet-cmds-helper",
619 "DEBUG",
620 NULL);
621 ni = GNUNET_new (struct NodeIdentifier);
622 ni->global_n = argv[1];
623 ni->local_m = argv[2];
624 ni->n = argv[3];
625 ni->m = argv[4];
626
627 LOG (GNUNET_ERROR_TYPE_ERROR,
628 "global_n: %s local_n: %s n: %s m: %s.\n",
629 ni->global_n,
630 ni->local_m,
631 ni->n,
632 ni->m);
633
634 status = GNUNET_OK;
635 if (NULL ==
636 (sigpipe = GNUNET_DISK_pipe (GNUNET_DISK_PF_NONE)))
637 {
638 GNUNET_break (0);
639 return 1;
640 }
641 shc_chld =
642 GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, &sighandler_child_death);
643 ret = GNUNET_PROGRAM_run (argc,
644 argv,
645 "gnunet-cmds-helper",
646 "Helper for starting a local interpreter loop",
647 options,
648 &run,
649 ni);
650 LOG (GNUNET_ERROR_TYPE_ERROR,
651 "run finished\n");
652 GNUNET_SIGNAL_handler_uninstall (shc_chld);
653 shc_chld = NULL;
654 GNUNET_DISK_pipe_close (sigpipe);
655 GNUNET_free (ni);
656 if (GNUNET_OK != ret)
657 return 1;
658 return (GNUNET_OK == status) ? 0 : 1;
659}
660
661
662/* end of gnunet-cmds-helper.c */
diff --git a/src/testing/test_testing_api_cmd_netjail.c b/src/testing/test_testing_api_cmd_netjail.c
new file mode 100644
index 000000000..543642109
--- /dev/null
+++ b/src/testing/test_testing_api_cmd_netjail.c
@@ -0,0 +1,79 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2021 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file testing/test_testbed_api_cmd_netjail.c
23 * @brief Test case executing a script in a network name space.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_testing_ng_lib.h"
28#include "gnunet_util_lib.h"
29
30
31/**
32 * Main function to run the test cases.
33 *
34 * @param cls not used.
35 *
36 */
37static void
38run (void *cls)
39{
40 struct GNUNET_TESTING_Command commands[] = {
41 GNUNET_TESTING_cmd_netjail_start ("netjail-start-1",
42 "2",
43 "2"),
44 GNUNET_TESTING_cmd_netjail_start_testing_system ("netjail-start-testbed-1",
45 "2",
46 "2",
47 "libgnunet_plugin_testcmd"),
48 GNUNET_TESTING_cmd_stop_testing_system ("stop-testbed",
49 "netjail-start-testbed-1",
50 "2",
51 "2"),
52 GNUNET_TESTING_cmd_netjail_stop ("netjail-stop-1",
53 "2",
54 "2"),
55 GNUNET_TESTING_cmd_end ()
56 };
57
58 GNUNET_TESTING_run (NULL,
59 commands,
60 GNUNET_TIME_UNIT_FOREVER_REL);
61}
62
63
64int
65main (int argc,
66 char *const *argv)
67{
68 int rv = 0;
69
70 GNUNET_log_setup ("test-netjail",
71 "DEBUG",
72 NULL);
73 GNUNET_SCHEDULER_run (&run,
74 NULL);
75
76 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
77 "Test finished!\n");
78 return rv;
79}
diff --git a/src/testing/test_testing_plugin_testcmd.c b/src/testing/test_testing_plugin_testcmd.c
new file mode 100644
index 000000000..aeb0db5dc
--- /dev/null
+++ b/src/testing/test_testing_plugin_testcmd.c
@@ -0,0 +1,116 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2013, 2014 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file testbed/plugin_testcmd.c
23 * @brief a plugin to provide the API for running test cases.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_testing_ng_lib.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_testing_ng_lib.h"
30
31/**
32 * Generic logging shortcut
33 */
34#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
35
36unsigned int are_all_peers_started;
37
38static void
39all_peers_started ()
40{
41 are_all_peers_started = GNUNET_YES;
42 LOG (GNUNET_ERROR_TYPE_ERROR,
43 "setting are_all_peers_started: %d\n",
44 are_all_peers_started);
45}
46
47static void
48start_testcase (TESTING_CMD_HELPER_write_cb write_message, char *router_ip,
49 char *node_ip,
50 char *n,
51 char *m,
52 char *local_m)
53{
54 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
55
56 LOG (GNUNET_ERROR_TYPE_ERROR,
57 "We got here 6!\n");
58
59 are_all_peers_started = GNUNET_NO;
60
61 struct GNUNET_TESTING_Command commands[] = {
62 GNUNET_TESTING_cmd_hello_world_birth ("hello-world-birth-0",
63 &now),
64 GNUNET_TESTING_cmd_hello_world ("hello-world-0","hello-world-birth-0",""),
65 GNUNET_TESTING_cmd_send_peer_ready ("send-peer-ready-1",
66 write_message),
67 GNUNET_TESTING_cmd_block_until_all_peers_started ("block-1",
68 &are_all_peers_started),
69 GNUNET_TESTING_cmd_local_test_finished ("local-test-finished-1",
70 write_message)
71 };
72
73 GNUNET_TESTING_run (NULL,
74 commands,
75 GNUNET_TIME_UNIT_FOREVER_REL);
76 LOG (GNUNET_ERROR_TYPE_ERROR,
77 "We got here 7!\n");
78
79}
80
81
82/**
83 * Entry point for the plugin.
84 *
85 * @param cls NULL
86 * @return the exported block API
87 */
88void *
89libgnunet_plugin_testcmd_init (void *cls)
90{
91 struct GNUNET_TESTING_PluginFunctions *api;
92
93 api = GNUNET_new (struct GNUNET_TESTING_PluginFunctions);
94 api->start_testcase = &start_testcase;
95 api->all_peers_started = &all_peers_started;
96 return api;
97}
98
99
100/**
101 * Exit point from the plugin.
102 *
103 * @param cls the return value from #libgnunet_plugin_block_test_init
104 * @return NULL
105 */
106void *
107libgnunet_plugin_testcmd_done (void *cls)
108{
109 struct GNUNET_TESTING_PluginFunctions *api = cls;
110
111 GNUNET_free (api);
112 return NULL;
113}
114
115
116/* end of plugin_testcmd.c */
diff --git a/src/testing/testing_api_cmd_block_until_all_peers_started.c b/src/testing/testing_api_cmd_block_until_all_peers_started.c
new file mode 100644
index 000000000..8659fbb46
--- /dev/null
+++ b/src/testing/testing_api_cmd_block_until_all_peers_started.c
@@ -0,0 +1,128 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2021 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file testing_api_cmd_block_until_all_peers_started.c
23 * @brief cmd to block the interpreter loop until all peers started.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_testing_ng_lib.h"
29
30/**
31 * Generic logging shortcut
32 */
33#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
34
35struct BlockState
36{
37 unsigned int *all_peers_started;
38};
39
40
41static int
42block_until_all_peers_started_traits (void *cls,
43 const void **ret,
44 const char *trait,
45 unsigned int index)
46{
47 return GNUNET_OK;
48}
49
50
51static void
52block_until_all_peers_started_cleanup (void *cls,
53 const struct GNUNET_TESTING_Command *cmd)
54{
55 struct BlockState *bs = cls;
56
57 GNUNET_free (bs);
58}
59
60
61static void
62block_until_all_peers_started_run (void *cls,
63 const struct GNUNET_TESTING_Command *cmd,
64 struct GNUNET_TESTING_Interpreter *is)
65{
66 LOG (GNUNET_ERROR_TYPE_ERROR,
67 "block_until_all_peers_started_run!\n");
68}
69
70
71static int
72block_until_all_peers_started_finish (void *cls,
73 GNUNET_SCHEDULER_TaskCallback cont,
74 void *cont_cls)
75{
76 struct BlockState *bs = cls;
77 unsigned int *ret = bs->all_peers_started;
78
79 LOG (GNUNET_ERROR_TYPE_ERROR,
80 "We got here 10\n");
81
82 if (GNUNET_YES == *ret)
83 {
84 LOG (GNUNET_ERROR_TYPE_ERROR,
85 "We do not need to block anymore!\n");
86 cont (cont_cls);
87 }
88 else
89 {
90 LOG (GNUNET_ERROR_TYPE_ERROR,
91 "You shall not pass!\n");
92 }
93
94 return *ret;
95}
96
97
98/**
99 * Create command.
100 *
101 * @param label name for command.
102 * @return command.
103 */
104struct GNUNET_TESTING_Command
105GNUNET_TESTING_cmd_block_until_all_peers_started (const char *label,
106 unsigned int *
107 all_peers_started)
108{
109 struct BlockState *bs;
110
111 LOG (GNUNET_ERROR_TYPE_ERROR,
112 "we have all_peers_started: %u\n",
113 *all_peers_started);
114
115 bs = GNUNET_new (struct BlockState);
116 bs->all_peers_started = all_peers_started;
117
118 struct GNUNET_TESTING_Command cmd = {
119 .cls = bs,
120 .label = label,
121 .run = &block_until_all_peers_started_run,
122 .finish = &block_until_all_peers_started_finish,
123 .cleanup = &block_until_all_peers_started_cleanup,
124 .traits = &block_until_all_peers_started_traits
125 };
126
127 return cmd;
128}
diff --git a/src/testing/testing_api_cmd_local_test_finished.c b/src/testing/testing_api_cmd_local_test_finished.c
new file mode 100644
index 000000000..5b74d4e04
--- /dev/null
+++ b/src/testing/testing_api_cmd_local_test_finished.c
@@ -0,0 +1,131 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2021 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file testing_api_cmd_block_until_all_peers_started.c
23 * @brief cmd to block the interpreter loop until all peers started.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_testing_ng_lib.h"
29#include "testing_cmds.h"
30
31/**
32 * Generic logging shortcut
33 */
34#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
35
36struct LocalFinishedState
37{
38 TESTING_CMD_HELPER_write_cb write_message;
39
40 struct GNUNET_CMDS_LOCAL_FINISHED *reply;
41};
42
43
44static int
45local_test_finished_traits (void *cls,
46 const void **ret,
47 const char *trait,
48 unsigned int index)
49{
50 return GNUNET_OK;
51}
52
53
54static void
55local_test_finished_cleanup (void *cls,
56 const struct GNUNET_TESTING_Command *cmd)
57{
58 struct LocalFinishedState *lfs = cls;
59
60 GNUNET_free (lfs->reply);
61 GNUNET_free (lfs);
62}
63
64
65static void
66local_test_finished_run (void *cls,
67 const struct GNUNET_TESTING_Command *cmd,
68 struct GNUNET_TESTING_Interpreter *is)
69{
70 struct LocalFinishedState *lfs = cls;
71
72 struct GNUNET_CMDS_LOCAL_FINISHED *reply;
73 size_t msg_length;
74
75 LOG (GNUNET_ERROR_TYPE_ERROR,
76 "We got here 12!\n");
77
78 msg_length = sizeof(struct GNUNET_CMDS_LOCAL_FINISHED);
79 reply = GNUNET_new (struct GNUNET_CMDS_LOCAL_FINISHED);
80 reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED);
81 reply->header.size = htons ((uint16_t) msg_length);
82 lfs->reply = reply;
83 lfs->write_message ((struct GNUNET_MessageHeader *) reply, msg_length);
84
85 LOG (GNUNET_ERROR_TYPE_ERROR,
86 "We got here 13!\n");
87}
88
89
90static int
91local_test_finished_finish (void *cls,
92 GNUNET_SCHEDULER_TaskCallback cont,
93 void *cont_cls)
94{
95 // This will stop the local loop without shutting down the scheduler, because we do not call the continuation, which is the interpreter_next method.
96 LOG (GNUNET_ERROR_TYPE_ERROR,
97 "Stopping local loop\n");
98 return GNUNET_YES;
99}
100
101
102/**
103 * Create command.
104 *
105 * @param label name for command.
106 * @return command.
107 */
108struct GNUNET_TESTING_Command
109GNUNET_TESTING_cmd_local_test_finished (const char *label,
110 TESTING_CMD_HELPER_write_cb
111 write_message)
112{
113 struct LocalFinishedState *lfs;
114
115 LOG (GNUNET_ERROR_TYPE_ERROR,
116 "We got here 11!\n");
117
118 lfs = GNUNET_new (struct LocalFinishedState);
119 lfs->write_message = write_message;
120
121 struct GNUNET_TESTING_Command cmd = {
122 .cls = lfs,
123 .label = label,
124 .run = &local_test_finished_run,
125 .finish = &local_test_finished_finish,
126 .cleanup = &local_test_finished_cleanup,
127 .traits = &local_test_finished_traits
128 };
129
130 return cmd;
131}
diff --git a/src/testing/testing_api_cmd_netjail_start.c b/src/testing/testing_api_cmd_netjail_start.c
new file mode 100644
index 000000000..c82392a08
--- /dev/null
+++ b/src/testing/testing_api_cmd_netjail_start.c
@@ -0,0 +1,217 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2021 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file testing/testing_api_cmd_hello_world.c
23 * @brief Command to start the netjail script.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_testing_ng_lib.h"
29
30#define NETJAIL_START_SCRIPT "./../testing/netjail_start.sh"
31
32struct NetJailState
33{
34 struct GNUNET_ChildWaitHandle *cwh;
35
36 char *local_m;
37
38 char *global_n;
39
40 /**
41 * The process id of the start script.
42 */
43 struct GNUNET_OS_Process *start_proc;
44
45 unsigned int finished;
46};
47
48
49/**
50*
51*
52* @param cls closure
53* @param cmd current CMD being cleaned up.
54*/
55static void
56netjail_start_cleanup (void *cls,
57 const struct GNUNET_TESTING_Command *cmd)
58{
59 struct NetJailState *ns = cls;
60
61 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
62 "netjail_start_cleanup!\n");
63
64 if (NULL != ns->cwh)
65 {
66 GNUNET_wait_child_cancel (ns->cwh);
67 ns->cwh = NULL;
68 }
69 if (NULL != ns->start_proc)
70 {
71 GNUNET_assert (0 ==
72 GNUNET_OS_process_kill (ns->start_proc,
73 SIGKILL));
74 GNUNET_assert (GNUNET_OK ==
75 GNUNET_OS_process_wait (ns->start_proc));
76 GNUNET_OS_process_destroy (ns->start_proc);
77 ns->start_proc = NULL;
78 }
79 GNUNET_free (ns);
80}
81
82
83/**
84*
85*
86* @param cls closure.
87* @param[out] ret result
88* @param trait name of the trait.
89* @param index index number of the object to offer.
90* @return #GNUNET_OK on success.
91*/
92static int
93netjail_start_traits (void *cls,
94 const void **ret,
95 const char *trait,
96 unsigned int index)
97{
98 return GNUNET_OK;
99}
100
101static void
102child_completed_callback (void *cls,
103 enum GNUNET_OS_ProcessStatusType type,
104 long unsigned int exit_code)
105{
106 struct NetJailState *ns = cls;
107
108 if (0 == exit_code)
109 {
110 ns->finished = GNUNET_YES;
111 }
112 else
113 {
114 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
115 "Child completed with an error!\n");
116 ns->finished = GNUNET_SYSERR;
117 }
118 GNUNET_OS_process_destroy (ns->start_proc);
119 ns->start_proc = NULL;
120}
121
122
123
124/**
125* Run the "hello world" CMD.
126*
127* @param cls closure.
128* @param cmd CMD being run.
129* @param is interpreter state.
130*/
131static void
132netjail_start_run (void *cls,
133 const struct GNUNET_TESTING_Command *cmd,
134 struct GNUNET_TESTING_Interpreter *is)
135{
136 struct NetJailState *ns = cls;
137 char *const script_argv[] = {NETJAIL_START_SCRIPT,
138 ns->local_m,
139 ns->global_n,
140 NULL};
141 unsigned int helper_check = GNUNET_OS_check_helper_binary (
142 NETJAIL_START_SCRIPT,
143 GNUNET_YES,
144 NULL);
145
146 if (GNUNET_NO == helper_check)
147 {
148 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
149 "No SUID for %s!\n",
150 NETJAIL_START_SCRIPT);
151 GNUNET_TESTING_interpreter_fail ();
152 }
153 else if (GNUNET_NO == helper_check)
154 {
155 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
156 "%s not found!\n",
157 NETJAIL_START_SCRIPT);
158 GNUNET_TESTING_interpreter_fail ();
159 }
160
161 ns->start_proc = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ERR,
162 NULL,
163 NULL,
164 NULL,
165 NETJAIL_START_SCRIPT,
166 script_argv);
167
168 ns->cwh = GNUNET_wait_child (ns->start_proc,
169 &child_completed_callback,
170 ns);
171 GNUNET_break (NULL != ns->cwh);
172}
173
174static int
175netjail_start_finish (void *cls,
176 GNUNET_SCHEDULER_TaskCallback cont,
177 void *cont_cls)
178{
179 struct NetJailState *ns = cls;
180
181 if (ns->finished)
182 {
183 cont (cont_cls);
184 }
185 return ns->finished;
186}
187
188/**
189 * Create command.
190 *
191 * @param label name for command.
192 * @param binaryname to start.
193 * @return command.
194 */
195struct GNUNET_TESTING_Command
196GNUNET_TESTING_cmd_netjail_start (const char *label,
197 char *local_m,
198 char *global_n)
199{
200 struct NetJailState *ns;
201
202 ns = GNUNET_new (struct NetJailState);
203 ns->local_m = local_m;
204 ns->global_n = global_n;
205 ns->finished = GNUNET_NO;
206
207 struct GNUNET_TESTING_Command cmd = {
208 .cls = ns,
209 .label = label,
210 .run = &netjail_start_run,
211 .finish = &netjail_start_finish,
212 .cleanup = &netjail_start_cleanup,
213 .traits = &netjail_start_traits
214 };
215
216 return cmd;
217}
diff --git a/src/testing/testing_api_cmd_netjail_start_testsystem.c b/src/testing/testing_api_cmd_netjail_start_testsystem.c
new file mode 100644
index 000000000..5c2f71168
--- /dev/null
+++ b/src/testing/testing_api_cmd_netjail_start_testsystem.c
@@ -0,0 +1,541 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2021 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file testing/testing_api_cmd_hello_world.c
23 * @brief Command to start the netjail peers.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_testing_ng_lib.h"
28#include "testing_cmds.h"
29
30#define NETJAIL_EXEC_SCRIPT "./../testing/netjail_exec.sh"
31
32struct HelperMessage;
33
34struct HelperMessage
35{
36
37 struct HelperMessage *next;
38
39 struct HelperMessage *prev;
40
41 /**
42 * Size of the original message.
43 */
44 uint16_t bytes_msg;
45
46 /* Followed by @e bytes_msg of msg.*/
47};
48
49
50
51struct NetJailState
52{
53
54 unsigned int *rv;
55
56 struct HelperMessage *hp_messages_head;
57
58 struct HelperMessage *hp_messages_tail;
59
60 /**
61 * The process handle
62 */
63 struct GNUNET_HELPER_Handle **helper;
64
65 unsigned int n_helper;
66
67 char *binary_name;
68
69 char *local_m;
70
71 char *global_n;
72
73 /**
74 * The send handle for the helper
75 */
76 struct GNUNET_HELPER_SendHandle **shandle;
77
78 unsigned int n_shandle;
79
80 /**
81 * The message corresponding to send handle
82 */
83 struct GNUNET_MessageHeader **msg;
84
85 unsigned int n_msg;
86
87 unsigned int number_of_testsystems_started;
88
89 unsigned int number_of_peers_started;
90
91 unsigned int number_of_local_test_finished;
92
93 char *plugin_name;
94};
95
96struct TestingSystemCount
97{
98 unsigned int count;
99
100 struct NetJailState *ns;
101};
102
103/**
104*
105*
106* @param cls closure
107* @param cmd current CMD being cleaned up.
108*/
109static void
110netjail_exec_cleanup (void *cls,
111 const struct GNUNET_TESTING_Command *cmd)
112{
113 struct NetJailState *ns = cls;
114
115 GNUNET_free (ns->binary_name);
116}
117
118
119/**
120*
121*
122* @param cls closure.
123* @param[out] ret result
124* @param trait name of the trait.
125* @param index index number of the object to offer.
126* @return #GNUNET_OK on success.
127*/
128static int
129netjail_exec_traits (void *cls,
130 const void **ret,
131 const char *trait,
132 unsigned int index)
133{
134 struct NetJailState *ns = cls;
135 struct GNUNET_HELPER_Handle **helper = ns->helper;
136 struct HelperMessage *hp_messages_head = ns->hp_messages_head;
137
138
139 struct GNUNET_TESTING_Trait traits[] = {
140 {
141 .index = 0,
142 .trait_name = "helper_handles",
143 .ptr = (const void *) helper,
144 },
145 {
146 .index = 1,
147 .trait_name = "hp_msgs_head",
148 .ptr = (const void *) hp_messages_head,
149 },
150 GNUNET_TESTING_trait_end ()
151 };
152
153 return GNUNET_TESTING_get_trait (traits,
154 ret,
155 trait,
156 index);
157}
158
159
160/**
161 * Offer handles to testing cmd helper from trait
162 *
163 * @param cmd command to extract the message from.
164 * @param pt pointer to message.
165 * @return #GNUNET_OK on success.
166 */
167int
168GNUNET_TESTING_get_trait_helper_handles (const struct
169 GNUNET_TESTING_Command *cmd,
170 struct GNUNET_HELPER_Handle ***helper)
171{
172 return cmd->traits (cmd->cls,
173 (const void **) helper,
174 "helper_handles",
175 (unsigned int) 0);
176}
177
178/**
179 * Offer messages received via testing cmd helper from trait
180 *
181 * @param cmd command to extract the message from.
182 * @param pt pointer to message.
183 * @return #GNUNET_OK on success.
184 */
185int
186GNUNET_TESTING_get_trait_helper_messages (const struct
187 GNUNET_TESTING_Command *cmd,
188 struct HelperMessage ***
189 hp_messages_head)
190{
191 return cmd->traits (cmd->cls,
192 (const void **) hp_messages_head,
193 "hp_msgs_head",
194 (unsigned int) 1);
195}
196
197
198/**
199 * Continuation function from GNUNET_HELPER_send()
200 *
201 * @param cls closure
202 * @param result GNUNET_OK on success,
203 * GNUNET_NO if helper process died
204 * GNUNET_SYSERR during GNUNET_HELPER_stop
205 */
206static void
207clear_msg (void *cls, int result)
208{
209 struct TestingSystemCount *tbc = cls;
210 struct NetJailState *ns = tbc->ns;
211
212 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
213 "clear_msg tbc->count: %d\n",
214 tbc->count);
215 GNUNET_assert (NULL != ns->shandle[tbc->count - 1]);
216 ns->shandle[tbc->count - 1] = NULL;
217 GNUNET_free (ns->msg[tbc->count - 1]);
218 ns->msg[tbc->count - 1] = NULL;
219}
220
221
222/**
223 * Functions with this signature are called whenever a
224 * complete message is received by the tokenizer.
225 *
226 * Do not call GNUNET_SERVER_mst_destroy in callback
227 *
228 * @param cls closure
229 * @param client identification of the client
230 * @param message the actual message
231 *
232 * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
233 */
234static int
235helper_mst (void *cls, const struct GNUNET_MessageHeader *message)
236{
237 struct TestingSystemCount *tbc = cls;
238 struct NetJailState *ns = tbc->ns;
239 struct HelperMessage *hp_msg;
240
241 if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY == ntohs (message->type))
242 {
243 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
244 "helper_mst tbc->count: %d\n",
245 tbc->count);
246 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
247 "Received message from helper.\n");
248 ns->number_of_testsystems_started++;
249 }
250 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED == ntohs (
251 message->type))
252 {
253 ns->number_of_peers_started++;
254 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
255 "number_of_peers_started: %d\n",
256 ns->number_of_peers_started);
257 }
258 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED == ntohs (
259 message->type))
260 {
261 ns->number_of_local_test_finished++;
262 }
263 else
264 {
265 hp_msg = GNUNET_new (struct HelperMessage);
266 hp_msg->bytes_msg = message->size;
267 memcpy (&hp_msg[1], message, message->size);
268 GNUNET_CONTAINER_DLL_insert (ns->hp_messages_head, ns->hp_messages_tail,
269 hp_msg);
270 }
271
272 return GNUNET_OK;
273}
274
275
276static void
277exp_cb (void *cls)
278{
279 struct NetJailState *ns = cls;
280 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called exp_cb.\n");
281 *ns->rv = 1;
282}
283
284
285static struct GNUNET_CMDS_HelperInit *
286create_helper_init_msg_ (char *m_char,
287 char *n_char,
288 const char *plugin_name)
289{
290 struct GNUNET_CMDS_HelperInit *msg;
291 uint16_t plugin_name_len;
292 uint16_t msg_size;
293
294 GNUNET_assert (NULL != plugin_name);
295 plugin_name_len = strlen (plugin_name);
296 msg_size = sizeof(struct GNUNET_CMDS_HelperInit) + plugin_name_len;
297 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
298 "msg_size: %d \n",
299 msg_size);
300 msg = GNUNET_malloc (msg_size);
301 msg->header.size = htons (msg_size);
302 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT);
303 msg->plugin_name_size = htons (plugin_name_len);
304 GNUNET_memcpy ((char *) &msg[1],
305 plugin_name,
306 plugin_name_len);
307 return msg;
308}
309
310
311static void
312start_helper (struct NetJailState *ns, struct
313 GNUNET_CONFIGURATION_Handle *config,
314 char *m_char,
315 char *n_char)
316{
317 // struct GNUNET_CONFIGURATION_Handle *cfg;
318 struct GNUNET_CMDS_HelperInit *msg;
319 struct TestingSystemCount *tbc;
320 char *const script_argv[] = {NETJAIL_EXEC_SCRIPT,
321 m_char,
322 n_char,
323 GNUNET_OS_get_libexec_binary_path (
324 HELPER_CMDS_BINARY),
325 ns->global_n,
326 ns->local_m,
327 NULL};
328 unsigned int m = atoi (m_char);
329 unsigned int n = atoi (n_char);
330 unsigned int helper_check = GNUNET_OS_check_helper_binary (
331 NETJAIL_EXEC_SCRIPT,
332 GNUNET_YES,
333 NULL);
334
335 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
336 "m: %d n: %d\n",
337 m,
338 n);
339
340 tbc = GNUNET_new (struct TestingSystemCount);
341 tbc->ns = ns;
342 tbc->count = (n - 1) * atoi (ns->local_m) + m;
343
344
345 if (GNUNET_NO == helper_check)
346 {
347 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
348 "No SUID for %s!\n",
349 NETJAIL_EXEC_SCRIPT);
350 *ns->rv = 1;
351 }
352 else if (GNUNET_NO == helper_check)
353 {
354 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
355 "%s not found!\n",
356 NETJAIL_EXEC_SCRIPT);
357 *ns->rv = 1;
358 }
359
360 GNUNET_array_append (ns->helper, ns->n_helper, GNUNET_HELPER_start (
361 GNUNET_YES,
362 NETJAIL_EXEC_SCRIPT,
363 script_argv,
364 &helper_mst,
365 &exp_cb,
366 tbc));
367
368 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
369 "First using helper %d %d\n",
370 tbc->count - 1,
371 ns->n_helper);
372 struct GNUNET_HELPER_Handle *helper = ns->helper[tbc->count - 1];
373
374 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
375 "First using helper %d %d %p\n",
376 tbc->count - 1,
377 ns->n_helper,
378 helper);
379
380 msg = create_helper_init_msg_ (m_char,
381 n_char,
382 ns->plugin_name);
383 GNUNET_array_append (ns->msg, ns->n_msg, &msg->header);
384
385 GNUNET_array_append (ns->shandle, ns->n_shandle, GNUNET_HELPER_send (
386 helper,
387 &msg->header,
388 GNUNET_NO,
389 &clear_msg,
390 tbc));
391
392 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
393 "Message %d send!\n",
394 tbc->count);
395
396 if (NULL == ns->shandle[tbc->count - 1])
397 {
398 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
399 "Send handle is NULL!\n");
400 GNUNET_free (msg);
401 *ns->rv = 1;
402 }
403}
404
405
406/**
407* Run the "hello world" CMD.
408*
409* @param cls closure.
410* @param cmd CMD being run.
411* @param is interpreter state.
412*/
413static void
414netjail_exec_run (void *cls,
415 const struct GNUNET_TESTING_Command *cmd,
416 struct GNUNET_TESTING_Interpreter *is)
417{
418 char str_m[12];
419 char str_n[12];
420 struct NetJailState *ns = cls;
421 struct GNUNET_CONFIGURATION_Handle *config =
422 GNUNET_CONFIGURATION_create ();
423
424 for (int i = 1; i <= atoi (ns->global_n); i++) {
425 for (int j = 1; j <= atoi (ns->local_m); j++)
426 {
427 sprintf (str_n, "%d", i);
428 sprintf (str_m, "%d", j);
429 start_helper (ns, config,
430 str_m,
431 str_n);
432 }
433 }
434}
435
436
437static int
438netjail_start_finish (void *cls,
439 GNUNET_SCHEDULER_TaskCallback cont,
440 void *cont_cls)
441{
442 unsigned int ret = GNUNET_NO;
443 struct NetJailState *ns = cls;
444 unsigned int total_number = atoi (ns->local_m) * atoi (ns->global_n);
445 struct GNUNET_CMDS_ALL_PEERS_STARTED *reply;
446 size_t msg_length;
447 struct GNUNET_HELPER_Handle *helper;
448 struct TestingSystemCount *tbc;
449
450 if (ns->number_of_local_test_finished == total_number)
451 {
452 ret = GNUNET_YES;
453 cont (cont_cls);
454 }
455
456 if (ns->number_of_testsystems_started == total_number)
457 {
458 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
459 "All helpers started!\n");
460 ns->number_of_testsystems_started = 0;
461 }
462
463 if (ns->number_of_peers_started == total_number)
464 {
465 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
466 "All peers started!\n");
467
468 for (int i = 1; i <= atoi (ns->global_n); i++) {
469 for (int j = 1; j <= atoi (ns->local_m); j++)
470 {
471 tbc = GNUNET_new (struct TestingSystemCount);
472 tbc->ns = ns;
473 // TODO This needs to be more generic. As we send more messages back and forth, we can not grow the arrays again and again, because this is to error prone.
474 tbc->count = (i - 1) * atoi (ns->local_m) + j + total_number;
475 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
476 "Second using helper %d %d %d\n",
477 tbc->count - 1 - total_number,
478 i,
479 j);
480 helper = ns->helper[tbc->count - 1 - total_number];
481 msg_length = sizeof(struct GNUNET_CMDS_ALL_PEERS_STARTED);
482 reply = GNUNET_new (struct GNUNET_CMDS_ALL_PEERS_STARTED);
483 reply->header.type = htons (
484 GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED);
485 reply->header.size = htons ((uint16_t) msg_length);
486
487 GNUNET_array_append (ns->msg, ns->n_msg, &reply->header);
488
489 struct GNUNET_HELPER_SendHandle *sh = GNUNET_HELPER_send (
490 helper,
491 &reply->header,
492 GNUNET_NO,
493 &clear_msg,
494 tbc);
495
496 GNUNET_array_append (ns->shandle, ns->n_shandle, sh);
497
498 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
499 "All peers started message %d send!\n",
500 tbc->count);
501 }
502 }
503 ns->number_of_peers_started = 0;
504 }
505 return ret;
506}
507
508
509/**
510 * Create command.
511 *
512 * @param label name for command.
513 * @param binaryname to exec.
514 * @return command.
515 */
516struct GNUNET_TESTING_Command
517GNUNET_TESTING_cmd_netjail_start_testing_system (const char *label,
518 char *local_m,
519 char *global_n,
520 char *plugin_name,
521 unsigned int *rv)
522{
523 struct NetJailState *ns;
524
525 ns = GNUNET_new (struct NetJailState);
526 ns->local_m = local_m;
527 ns->global_n = global_n;
528 ns->plugin_name = plugin_name;
529 ns->rv = rv;
530
531 struct GNUNET_TESTING_Command cmd = {
532 .cls = ns,
533 .label = label,
534 .run = &netjail_exec_run,
535 .finish = &netjail_start_finish,
536 .cleanup = &netjail_exec_cleanup,
537 .traits = &netjail_exec_traits
538 };
539
540 return cmd;
541}
diff --git a/src/testing/testing_api_cmd_netjail_stop.c b/src/testing/testing_api_cmd_netjail_stop.c
new file mode 100644
index 000000000..710b4fbf4
--- /dev/null
+++ b/src/testing/testing_api_cmd_netjail_stop.c
@@ -0,0 +1,215 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2021 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file testing/testing_api_cmd_hello_world.c
23 * @brief Command to stop the netjail script.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_testing_ng_lib.h"
29
30
31#define NETJAIL_STOP_SCRIPT "./../testing/netjail_stop.sh"
32
33struct GNUNET_ChildWaitHandle *cwh;
34
35struct NetJailState
36{
37 char *local_m;
38
39 char *global_n;
40
41 /**
42 * The process id of the start script.
43 */
44 struct GNUNET_OS_Process *stop_proc;
45
46 unsigned int finished;
47};
48
49
50/**
51*
52*
53* @param cls closure
54* @param cmd current CMD being cleaned up.
55*/
56static void
57netjail_stop_cleanup (void *cls,
58 const struct GNUNET_TESTING_Command *cmd)
59{
60 struct NetJailState *ns = cls;
61
62 if (NULL != cwh)
63 {
64 GNUNET_wait_child_cancel (cwh);
65 cwh = NULL;
66 }
67 if (NULL != ns->stop_proc)
68 {
69 GNUNET_assert (0 ==
70 GNUNET_OS_process_kill (ns->stop_proc,
71 SIGKILL));
72 GNUNET_assert (GNUNET_OK ==
73 GNUNET_OS_process_wait (ns->stop_proc));
74 GNUNET_OS_process_destroy (ns->stop_proc);
75 ns->stop_proc = NULL;
76 }
77}
78
79
80/**
81*
82*
83* @param cls closure.
84* @param[out] ret result
85* @param trait name of the trait.
86* @param index index number of the object to offer.
87* @return #GNUNET_OK on success.
88*/
89static int
90netjail_stop_traits (void *cls,
91 const void **ret,
92 const char *trait,
93 unsigned int index)
94{
95 return GNUNET_OK;
96}
97
98
99static void
100child_completed_callback (void *cls,
101 enum GNUNET_OS_ProcessStatusType type,
102 long unsigned int exit_code)
103{
104 struct NetJailState *ns = cls;
105
106 cwh = NULL;
107 if (0 == exit_code)
108 {
109 ns->finished = GNUNET_YES;
110 }
111 else
112 {
113 ns->finished = GNUNET_SYSERR;
114 }
115 GNUNET_OS_process_destroy (ns->stop_proc);
116 ns->stop_proc = NULL;
117}
118
119
120/**
121* Run the "hello world" CMD.
122*
123* @param cls closure.
124* @param cmd CMD being run.
125* @param is interpreter state.
126*/
127static void
128netjail_stop_run (void *cls,
129 const struct GNUNET_TESTING_Command *cmd,
130 struct GNUNET_TESTING_Interpreter *is)
131{
132 struct NetJailState *ns = cls;
133 char *const script_argv[] = {NETJAIL_STOP_SCRIPT,
134 ns->local_m,
135 ns->global_n,
136 NULL};
137 unsigned int helper_check = GNUNET_OS_check_helper_binary (
138 NETJAIL_STOP_SCRIPT,
139 GNUNET_YES,
140 NULL);
141
142 if (GNUNET_NO == helper_check)
143 {
144 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
145 "No SUID for %s!\n",
146 NETJAIL_STOP_SCRIPT);
147 GNUNET_TESTING_interpreter_fail ();
148 }
149 else if (GNUNET_NO == helper_check)
150 {
151 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
152 "%s not found!\n",
153 NETJAIL_STOP_SCRIPT);
154 GNUNET_TESTING_interpreter_fail ();
155 }
156
157 ns->stop_proc = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ERR,
158 NULL,
159 NULL,
160 NULL,
161 NETJAIL_STOP_SCRIPT,
162 script_argv);
163
164 cwh = GNUNET_wait_child (ns->stop_proc,
165 &child_completed_callback,
166 ns);
167 GNUNET_break (NULL != cwh);
168
169}
170
171
172static int
173netjail_stop_finish (void *cls,
174 GNUNET_SCHEDULER_TaskCallback cont,
175 void *cont_cls)
176{
177 struct NetJailState *ns = cls;
178
179 if (ns->finished)
180 {
181 cont (cont_cls);
182 }
183 return ns->finished;
184}
185
186
187/**
188 * Create command.
189 *
190 * @param label name for command.
191 * @param binaryname to stop.
192 * @return command.
193 */
194struct GNUNET_TESTING_Command
195GNUNET_TESTING_cmd_netjail_stop (const char *label,
196 char *local_m,
197 char *global_n)
198{
199 struct NetJailState *ns;
200
201 ns = GNUNET_new (struct NetJailState);
202 ns->local_m = local_m;
203 ns->global_n = global_n;
204
205 struct GNUNET_TESTING_Command cmd = {
206 .cls = ns,
207 .label = label,
208 .run = &netjail_stop_run,
209 .finish = &netjail_stop_finish,
210 .cleanup = &netjail_stop_cleanup,
211 .traits = &netjail_stop_traits
212 };
213
214 return cmd;
215}
diff --git a/src/testing/testing_api_cmd_netjail_stop_testsystem.c b/src/testing/testing_api_cmd_netjail_stop_testsystem.c
new file mode 100644
index 000000000..bed9f3ebf
--- /dev/null
+++ b/src/testing/testing_api_cmd_netjail_stop_testsystem.c
@@ -0,0 +1,141 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2021 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file testing/testing_api_cmd_hello_world.c
23 * @brief Command to start the netjail peers.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_testing_ng_lib.h"
28#include "testing_cmds.h"
29
30
31struct StopHelperState
32{
33
34 const char *helper_start_label;
35
36 /**
37 * The process handle
38 */
39 struct GNUNET_HELPER_Handle **helper;
40
41 char *local_m;
42
43 char *global_n;
44};
45
46
47/**
48*
49*
50* @param cls closure
51* @param cmd current CMD being cleaned up.
52*/
53static void
54stop_testing_system_cleanup (void *cls,
55 const struct GNUNET_TESTING_Command *cmd)
56{
57
58}
59
60
61/**
62*
63*
64* @param cls closure.
65* @param[out] ret result
66* @param trait name of the trait.
67* @param index index number of the object to offer.
68* @return #GNUNET_OK on success.
69*/
70static int
71stop_testing_system_traits (void *cls,
72 const void **ret,
73 const char *trait,
74 unsigned int index)
75{
76 return GNUNET_OK;
77}
78
79
80/**
81* Run the "hello world" CMD.
82*
83* @param cls closure.
84* @param cmd CMD being run.
85* @param is interpreter state.
86*/
87static void
88stop_testing_system_run (void *cls,
89 const struct GNUNET_TESTING_Command *cmd,
90 struct GNUNET_TESTING_Interpreter *is)
91{
92 struct StopHelperState *shs = cls;
93 struct GNUNET_HELPER_Handle **helper;
94 const struct GNUNET_TESTING_Command *start_helper_cmd;
95
96 start_helper_cmd = GNUNET_TESTING_interpreter_lookup_command (
97 shs->helper_start_label);
98 GNUNET_TESTING_get_trait_helper_handles (start_helper_cmd,
99 &helper);
100
101 for (int i = 1; i <= atoi (shs->global_n); i++) {
102 for (int j = 1; j <= atoi (shs->local_m); j++)
103 {
104 GNUNET_HELPER_stop (helper[(i - 1) * atoi (shs->local_m) + j - 1],
105 GNUNET_YES);
106 }
107 }
108}
109
110
111/**
112 * Create command.
113 *
114 * @param label name for command.
115 * @param binaryname to exec.
116 * @return command.
117 */
118struct GNUNET_TESTING_Command
119GNUNET_TESTING_cmd_stop_testing_system (const char *label,
120 const char *helper_start_label,
121 char *local_m,
122 char *global_n
123 )
124{
125 struct StopHelperState *shs;
126
127 shs = GNUNET_new (struct StopHelperState);
128 shs->helper_start_label = helper_start_label;
129 shs->local_m = local_m;
130 shs->global_n = global_n;
131
132 struct GNUNET_TESTING_Command cmd = {
133 .cls = shs,
134 .label = label,
135 .run = &stop_testing_system_run,
136 .cleanup = &stop_testing_system_cleanup,
137 .traits = &stop_testing_system_traits
138 };
139
140 return cmd;
141}
diff --git a/src/testing/testing_api_cmd_send_peer_ready.c b/src/testing/testing_api_cmd_send_peer_ready.c
index e5e004924..afe28de77 100644
--- a/src/testing/testing_api_cmd_send_peer_ready.c
+++ b/src/testing/testing_api_cmd_send_peer_ready.c
@@ -26,8 +26,7 @@
26#include "platform.h" 26#include "platform.h"
27#include "gnunet_util_lib.h" 27#include "gnunet_util_lib.h"
28#include "gnunet_testing_ng_lib.h" 28#include "gnunet_testing_ng_lib.h"
29#include "testbed_api.h" 29#include "testing_cmds.h"
30#include "testbed_helper.h"
31 30
32 31
33struct SendPeerReadyState 32struct SendPeerReadyState
@@ -68,7 +67,7 @@ send_peer_ready_run (void *cls,
68 struct GNUNET_CMDS_PEER_STARTED *reply; 67 struct GNUNET_CMDS_PEER_STARTED *reply;
69 size_t msg_length; 68 size_t msg_length;
70 69
71 msg_length = sizeof(struct GNUNET_CMDS_HelperInit);// GNUNET_CMDS_PEER_STARTED); 70 msg_length = sizeof(struct GNUNET_CMDS_PEER_STARTED);
72 reply = GNUNET_new (struct GNUNET_CMDS_PEER_STARTED); 71 reply = GNUNET_new (struct GNUNET_CMDS_PEER_STARTED);
73 reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED); 72 reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED);
74 reply->header.size = htons ((uint16_t) msg_length); 73 reply->header.size = htons ((uint16_t) msg_length);
diff --git a/src/testing/testing_cmds.h b/src/testing/testing_cmds.h
new file mode 100644
index 000000000..7a5860aea
--- /dev/null
+++ b/src/testing/testing_cmds.h
@@ -0,0 +1,90 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2021 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file testing/testing_cmds.h
23 * @brief Message formats for communication between testing cmds helper and testcase plugins.
24 * @author t3sserakt
25 */
26
27#ifndef TESTING_CMDS_H
28#define TESTING_CMDS_H
29
30#define HELPER_CMDS_BINARY "gnunet-cmds-helper"
31
32GNUNET_NETWORK_STRUCT_BEGIN
33
34/**
35 * Initialization message for gnunet-cmds-testbed to start cmd binary.
36 */
37struct GNUNET_CMDS_HelperInit
38{
39 /**
40 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT
41 */
42 struct GNUNET_MessageHeader header;
43
44 /**
45 *
46 */
47 uint16_t plugin_name_size GNUNET_PACKED;
48
49 /* Followed by plugin name of the plugin running the test case. This is not NULL
50 * terminated */
51};
52
53/**
54 * Reply message from cmds helper process
55 */
56struct GNUNET_CMDS_HelperReply
57{
58 /**
59 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY
60 */
61 struct GNUNET_MessageHeader header;
62};
63
64struct GNUNET_CMDS_PEER_STARTED
65{
66 /**
67 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED
68 */
69 struct GNUNET_MessageHeader header;
70};
71
72struct GNUNET_CMDS_ALL_PEERS_STARTED
73{
74 /**
75 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED
76 */
77 struct GNUNET_MessageHeader header;
78};
79
80struct GNUNET_CMDS_LOCAL_FINISHED
81{
82 /**
83 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED
84 */
85 struct GNUNET_MessageHeader header;
86};
87
88GNUNET_NETWORK_STRUCT_END
89#endif
90/* end of testing_cmds.h */