aboutsummaryrefslogtreecommitdiff
path: root/src/testing
diff options
context:
space:
mode:
Diffstat (limited to 'src/testing')
-rw-r--r--src/testing/Makefile.am50
-rw-r--r--src/testing/gnunet-cmds-helper.c566
-rwxr-xr-xsrc/testing/netjail_core.sh116
-rwxr-xr-xsrc/testing/netjail_exec.sh16
-rwxr-xr-xsrc/testing/netjail_start.sh52
-rwxr-xr-xsrc/testing/netjail_stop.sh26
-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.c139
-rw-r--r--src/testing/testing_api_cmd_local_test_finished.c151
-rw-r--r--src/testing/testing_api_cmd_netjail_start.c229
-rw-r--r--src/testing/testing_api_cmd_netjail_start_testsystem.c630
-rw-r--r--src/testing/testing_api_cmd_netjail_stop.c225
-rw-r--r--src/testing/testing_api_cmd_netjail_stop_testsystem.c143
-rw-r--r--src/testing/testing_api_cmd_send_peer_ready.c36
-rw-r--r--src/testing/testing_api_cmd_system_create.c25
-rw-r--r--src/testing/testing_api_cmd_system_destroy.c116
-rw-r--r--src/testing/testing_api_loop.c44
-rw-r--r--src/testing/testing_cmds.h90
19 files changed, 2832 insertions, 17 deletions
diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am
index 868e3fcec..038f0cb08 100644
--- a/src/testing/Makefile.am
+++ b/src/testing/Makefile.am
@@ -11,12 +11,46 @@ 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 = \
18 testing.c \ 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 \
51 testing.c testing.h \
19 testing_api_cmd_system_create.c \ 52 testing_api_cmd_system_create.c \
53 testing_api_cmd_system_destroy.c \
20 testing_api_cmd_batch.c \ 54 testing_api_cmd_batch.c \
21 testing_api_cmd_hello_world.c \ 55 testing_api_cmd_hello_world.c \
22 testing_api_cmd_hello_world_birth.c \ 56 testing_api_cmd_hello_world_birth.c \
@@ -28,9 +62,6 @@ libgnunettesting_la_LIBADD = \
28 $(top_builddir)/src/arm/libgnunetarm.la \ 62 $(top_builddir)/src/arm/libgnunetarm.la \
29 $(top_builddir)/src/util/libgnunetutil.la \ 63 $(top_builddir)/src/util/libgnunetutil.la \
30 $(LTLIBINTL) 64 $(LTLIBINTL)
31libgnunettesting_la_DEPENDENCIES = \
32 $(top_builddir)/src/arm/libgnunetarm.la \
33 $(top_builddir)/src/util/libgnunetutil.la
34libgnunettesting_la_LDFLAGS = \ 65libgnunettesting_la_LDFLAGS = \
35 $(GN_LIB_LDFLAGS) \ 66 $(GN_LIB_LDFLAGS) \
36 -version-info 2:0:1 67 -version-info 2:0:1
@@ -56,6 +87,7 @@ list_keys_LDADD = \
56 87
57 88
58check_PROGRAMS = \ 89check_PROGRAMS = \
90 test_testing_api_cmd_netjail \
59 test_testing_hello_world \ 91 test_testing_hello_world \
60 test_testing_portreservation \ 92 test_testing_portreservation \
61 test_testing_servicestartup \ 93 test_testing_servicestartup \
@@ -66,6 +98,7 @@ check_PROGRAMS = \
66if ENABLE_TEST_RUN 98if 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; 99AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME;
68TESTS = \ 100TESTS = \
101 test_testing_api_cmd_netjail \
69 test_testing_hello_world \ 102 test_testing_hello_world \
70 test_testing_portreservation \ 103 test_testing_portreservation \
71 test_testing_peerstartup \ 104 test_testing_peerstartup \
@@ -73,6 +106,12 @@ TESTS = \
73 test_testing_servicestartup 106 test_testing_servicestartup
74endif 107endif
75 108
109test_testing_api_cmd_netjail_SOURCES = \
110 test_testing_api_cmd_netjail.c
111test_testing_api_cmd_netjail_LDADD = \
112 libgnunettesting.la \
113 $(top_builddir)/src/util/libgnunetutil.la
114
76test_testing_hello_world_SOURCES = \ 115test_testing_hello_world_SOURCES = \
77 test_testing_hello_world.c 116 test_testing_hello_world.c
78test_testing_hello_world_LDADD = \ 117test_testing_hello_world_LDADD = \
@@ -111,4 +150,5 @@ test_testing_sharedservices_LDADD = \
111 150
112EXTRA_DIST = \ 151EXTRA_DIST = \
113 test_testing_defaults.conf \ 152 test_testing_defaults.conf \
114 test_testing_sharedservices.conf 153 test_testing_sharedservices.conf \
154 testing_cmds.h
diff --git a/src/testing/gnunet-cmds-helper.c b/src/testing/gnunet-cmds-helper.c
new file mode 100644
index 000000000..21ea33888
--- /dev/null
+++ b/src/testing/gnunet-cmds-helper.c
@@ -0,0 +1,566 @@
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 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
50testing_api_cmd_block_until_all_peers_started.c */
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 /**
78 * IP address of the specific node the helper is running for.
79 *
80 */
81 char *node_ip;
82
83 /**
84 * Name of the test case plugin.
85 *
86 */
87 char *plugin_name;
88
89 /**
90 * The number of namespaces
91 *
92 */
93 char *global_n;
94
95 /**
96 * The number of local nodes per namespace.
97 *
98 */
99 char *local_m;
100
101 /**
102 * The number of the namespace this node is in.
103 *
104 */
105 char *n;
106
107 /**
108 * The number of the node in the namespace.
109 *
110 */
111 char *m;
112};
113
114/**
115 * Struct with information about a specific node and the whole network namespace setup.
116 *
117 */
118struct NodeIdentifier
119{
120 /**
121 * The number of the namespace this node is in.
122 *
123 */
124 char *n;
125
126 /**
127 * The number of the node in the namespace.
128 *
129 */
130 char *m;
131
132 /**
133 * The number of namespaces
134 *
135 */
136 char *global_n;
137
138 /**
139 * The number of local nodes per namespace.
140 *
141 */
142 char *local_m;
143};
144
145/**
146 * Context for a single write on a chunk of memory
147 */
148struct WriteContext
149{
150 /**
151 * The data to write
152 */
153 void *data;
154
155 /**
156 * The length of the data
157 */
158 size_t length;
159
160 /**
161 * The current position from where the write operation should begin
162 */
163 size_t pos;
164};
165
166struct Plugin *plugin;
167
168/**
169 * The process handle to the testbed service
170
171static struct GNUNET_OS_Process *cmd_binary_process;*/
172
173/**
174 * Handle to the testing system
175 */
176static struct GNUNET_TESTING_System *test_system;
177
178/**
179 * Our message stream tokenizer
180 */
181struct GNUNET_MessageStreamTokenizer *tokenizer;
182
183/**
184 * Disk handle from stdin
185 */
186static struct GNUNET_DISK_FileHandle *stdin_fd;
187
188/**
189 * Disk handle for stdout
190 */
191static struct GNUNET_DISK_FileHandle *stdout_fd;
192
193/**
194 * Pipe used to communicate shutdown via signal.
195 */
196static struct GNUNET_DISK_PipeHandle *sigpipe;
197
198/**
199 * Task identifier for the read task
200 */
201static struct GNUNET_SCHEDULER_Task *read_task_id;
202
203/**
204 * Task identifier for the write task
205 */
206static struct GNUNET_SCHEDULER_Task *write_task_id;
207
208/**
209 * Are we done reading messages from stdin?
210 */
211static int done_reading;
212
213/**
214 * Result to return in case we fail
215 */
216static int status;
217
218
219/**
220 * Task to shut down cleanly
221 *
222 * @param cls NULL
223 */
224static void
225shutdown_task (void *cls)
226{
227
228 LOG_DEBUG ("Shutting down.\n");
229
230 if (NULL != read_task_id)
231 {
232 GNUNET_SCHEDULER_cancel (read_task_id);
233 read_task_id = NULL;
234 }
235 if (NULL != write_task_id)
236 {
237 struct WriteContext *wc;
238
239 wc = GNUNET_SCHEDULER_cancel (write_task_id);
240 write_task_id = NULL;
241 GNUNET_free (wc->data);
242 GNUNET_free (wc);
243 }
244 if (NULL != stdin_fd)
245 (void) GNUNET_DISK_file_close (stdin_fd);
246 if (NULL != stdout_fd)
247 (void) GNUNET_DISK_file_close (stdout_fd);
248 GNUNET_MST_destroy (tokenizer);
249 tokenizer = NULL;
250
251 if (NULL != test_system)
252 {
253 GNUNET_TESTING_system_destroy (test_system, GNUNET_YES);
254 test_system = NULL;
255 }
256}
257
258
259/**
260 * Task to write to the standard out
261 *
262 * @param cls the WriteContext
263 */
264static void
265write_task (void *cls)
266{
267 struct WriteContext *wc = cls;
268 ssize_t bytes_wrote;
269
270 GNUNET_assert (NULL != wc);
271 write_task_id = NULL;
272 bytes_wrote = GNUNET_DISK_file_write (stdout_fd,
273 wc->data + wc->pos,
274 wc->length - wc->pos);
275 if (GNUNET_SYSERR == bytes_wrote)
276 {
277 LOG (GNUNET_ERROR_TYPE_WARNING,
278 "Cannot reply back successful initialization\n");
279 GNUNET_free (wc->data);
280 GNUNET_free (wc);
281 return;
282 }
283 wc->pos += bytes_wrote;
284 if (wc->pos == wc->length)
285 {
286 GNUNET_free (wc->data);
287 GNUNET_free (wc);
288 return;
289 }
290 write_task_id = GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
291 stdout_fd,
292 &write_task,
293 wc);
294}
295
296
297/**
298 * Callback to write a message to the master loop.
299 *
300 */
301static void
302write_message (struct GNUNET_MessageHeader *message, size_t msg_length)
303{
304 struct WriteContext *wc;
305
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}
315
316
317/**
318 * Functions with this signature are called whenever a
319 * complete message is received by the tokenizer.
320 *
321 * Do not call #GNUNET_mst_destroy() in this callback
322 *
323 * @param cls identification of the client
324 * @param message the actual message
325 * @return #GNUNET_OK on success,
326 * #GNUNET_NO to stop further processing (no error)
327 * #GNUNET_SYSERR to stop further processing with error
328 */
329static int
330tokenizer_cb (void *cls, const struct GNUNET_MessageHeader *message)
331{
332 struct NodeIdentifier *ni = cls;
333 const struct GNUNET_CMDS_HelperInit *msg;
334 struct GNUNET_CMDS_HelperReply *reply;
335 char *binary;
336 char *plugin_name;
337 size_t plugin_name_size;
338 uint16_t msize;
339 size_t msg_length;
340 char *router_ip;
341 char *node_ip;
342
343 msize = ntohs (message->size);
344 if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT == ntohs (message->type))
345 {
346 msg = (const struct GNUNET_CMDS_HelperInit *) message;
347 plugin_name_size = ntohs (msg->plugin_name_size);
348 if ((sizeof(struct GNUNET_CMDS_HelperInit) + plugin_name_size) > msize)
349 {
350 GNUNET_break (0);
351 LOG (GNUNET_ERROR_TYPE_WARNING,
352 "Received unexpected message -- exiting\n");
353 goto error;
354 }
355 plugin_name = GNUNET_malloc (plugin_name_size + 1);
356 GNUNET_strlcpy (plugin_name,
357 ((char *) &msg[1]),
358 plugin_name_size + 1);
359
360 binary = GNUNET_OS_get_libexec_binary_path ("gnunet-cmd");
361
362 plugin = GNUNET_new (struct Plugin);
363 plugin->api = GNUNET_PLUGIN_load (plugin_name,
364 NULL);
365 plugin->library_name = GNUNET_strdup (basename (plugin_name));
366
367 plugin->global_n = ni->global_n;
368 plugin->local_m = ni->local_m;
369 plugin->n = ni->n;
370 plugin->m = ni->m;
371
372 router_ip = GNUNET_malloc (strlen (ROUTER_BASE_IP) + strlen (plugin->m)
373 + 1);
374 strcpy (router_ip, ROUTER_BASE_IP);
375 strcat (router_ip, plugin->m);
376
377 node_ip = GNUNET_malloc (strlen (NODE_BASE_IP) + strlen (plugin->n) + 1);
378 strcat (node_ip, NODE_BASE_IP);
379 strcat (node_ip, plugin->n);
380
381 plugin->api->start_testcase (&write_message, router_ip, node_ip, plugin->m,
382 plugin->n, plugin->local_m);
383
384 GNUNET_free (binary);
385
386 msg_length = sizeof(struct GNUNET_CMDS_HelperReply);
387 reply = GNUNET_new (struct GNUNET_CMDS_HelperReply);
388 reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY);
389 reply->header.size = htons ((uint16_t) msg_length);
390
391 write_message ((struct GNUNET_MessageHeader *) reply, msg_length);
392
393 return GNUNET_OK;
394 }
395 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED == ntohs (
396 message->type))
397 {
398 plugin->api->all_peers_started ();
399 return GNUNET_OK;
400 }
401 else
402 {
403 LOG (GNUNET_ERROR_TYPE_WARNING, "Received unexpected message -- exiting\n");
404 goto error;
405 }
406
407
408 error:
409 status = GNUNET_SYSERR;
410 LOG (GNUNET_ERROR_TYPE_ERROR,
411 "tokenizer shutting down!\n");
412 GNUNET_SCHEDULER_shutdown ();
413 return GNUNET_SYSERR;
414}
415
416
417/**
418 * Task to read from stdin
419 *
420 * @param cls NULL
421 */
422static void
423read_task (void *cls)
424{
425 char buf[GNUNET_MAX_MESSAGE_SIZE];
426 ssize_t sread;
427
428 read_task_id = NULL;
429 sread = GNUNET_DISK_file_read (stdin_fd, buf, sizeof(buf));
430 if ((GNUNET_SYSERR == sread) || (0 == sread))
431 {
432 LOG_DEBUG ("STDIN closed\n");
433 GNUNET_SCHEDULER_shutdown ();
434 return;
435 }
436 if (GNUNET_YES == done_reading)
437 {
438 /* didn't expect any more data! */
439 GNUNET_break_op (0);
440 LOG (GNUNET_ERROR_TYPE_ERROR,
441 "tokenizer shutting down during reading, didn't expect any more data!\n");
442 GNUNET_SCHEDULER_shutdown ();
443 return;
444 }
445 LOG_DEBUG ("Read %u bytes\n", (unsigned int) sread);
446 /* FIXME: could introduce a GNUNET_MST_read2 to read
447 directly from 'stdin_fd' and save a memcpy() here */
448 if (GNUNET_OK !=
449 GNUNET_MST_from_buffer (tokenizer, buf, sread, GNUNET_NO, GNUNET_NO))
450 {
451 GNUNET_break (0);
452 LOG (GNUNET_ERROR_TYPE_ERROR,
453 "tokenizer shutting down during reading, writing to buffer failed!\n");
454 GNUNET_SCHEDULER_shutdown ();
455 return;
456 }
457 read_task_id /* No timeout while reading */
458 = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
459 stdin_fd,
460 &read_task,
461 NULL);
462}
463
464
465/**
466 * Main function that will be run.
467 *
468 * @param cls closure
469 * @param args remaining command-line arguments
470 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
471 * @param cfg configuration
472 */
473static void
474run (void *cls,
475 char *const *args,
476 const char *cfgfile,
477 const struct GNUNET_CONFIGURATION_Handle *cfg)
478{
479 struct NodeIdentifier *ni = cls;
480
481 LOG_DEBUG ("Starting interpreter loop helper...\n");
482
483 tokenizer = GNUNET_MST_create (&tokenizer_cb, ni);
484 stdin_fd = GNUNET_DISK_get_handle_from_native (stdin);
485 stdout_fd = GNUNET_DISK_get_handle_from_native (stdout);
486 read_task_id = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
487 stdin_fd,
488 &read_task,
489 NULL);
490 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
491}
492
493
494/**
495 * Signal handler called for SIGCHLD.
496 */
497static void
498sighandler_child_death ()
499{
500 static char c;
501 int old_errno; /* back-up errno */
502
503 old_errno = errno;
504 GNUNET_break (
505 1 ==
506 GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle (sigpipe,
507 GNUNET_DISK_PIPE_END_WRITE),
508 &c,
509 sizeof(c)));
510 errno = old_errno;
511}
512
513
514/**
515 * Main function
516 *
517 * @param argc the number of command line arguments
518 * @param argv command line arg array
519 * @return return code
520 */
521int
522main (int argc, char **argv)
523{
524 struct NodeIdentifier *ni;
525 struct GNUNET_SIGNAL_Context *shc_chld;
526 struct GNUNET_GETOPT_CommandLineOption options[] =
527 { GNUNET_GETOPT_OPTION_END };
528 int ret;
529
530 GNUNET_log_setup ("gnunet-cmds-helper",
531 "DEBUG",
532 NULL);
533 ni = GNUNET_new (struct NodeIdentifier);
534 ni->global_n = argv[1];
535 ni->local_m = argv[2];
536 ni->n = argv[3];
537 ni->m = argv[4];
538
539 status = GNUNET_OK;
540 if (NULL ==
541 (sigpipe = GNUNET_DISK_pipe (GNUNET_DISK_PF_NONE)))
542 {
543 GNUNET_break (0);
544 return 1;
545 }
546 shc_chld =
547 GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, &sighandler_child_death);
548 ret = GNUNET_PROGRAM_run (argc,
549 argv,
550 "gnunet-cmds-helper",
551 "Helper for starting a local interpreter loop",
552 options,
553 &run,
554 ni);
555
556 GNUNET_SIGNAL_handler_uninstall (shc_chld);
557 shc_chld = NULL;
558 GNUNET_DISK_pipe_close (sigpipe);
559 GNUNET_free (ni);
560 if (GNUNET_OK != ret)
561 return 1;
562 return (GNUNET_OK == status) ? 0 : 1;
563}
564
565
566/* end of gnunet-cmds-helper.c */
diff --git a/src/testing/netjail_core.sh b/src/testing/netjail_core.sh
new file mode 100755
index 000000000..cf350d3fa
--- /dev/null
+++ b/src/testing/netjail_core.sh
@@ -0,0 +1,116 @@
1#!/bin/sh
2#
3
4
5
6# running with `sudo` is required to be
7# able running the actual commands as the
8# original user.
9
10export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
11
12netjail_check() {
13 NODE_COUNT=$1
14
15 FD_COUNT=$(($(ls /proc/self/fd | wc -w) - 4))
16
17 # quit if `$FD_COUNT < ($LOCAL_M * $GLOBAL_N * 2)`:
18 # the script also requires `sudo -C ($FD_COUNT + 4)`
19 # so you need 'Defaults closefrom_override' in the
20 # sudoers file.
21
22 if [ $FD_COUNT -lt $(($NODE_COUNT * 2)) ]; then
23 echo "File descriptors do not match requirements!" >&2
24 exit 1
25 fi
26}
27
28netjail_print_name() {
29 printf "%s%02x%02x" $1 $2 ${3:-0}
30}
31
32netjail_bridge() {
33 BRIDGE=$1
34
35 ip link add $BRIDGE type bridge
36 ip link set dev $BRIDGE up
37}
38
39netjail_bridge_clear() {
40 BRIDGE=$1
41
42 ip link delete $BRIDGE
43}
44
45netjail_node() {
46 NODE=$1
47
48 ip netns add $NODE
49}
50
51netjail_node_clear() {
52 NODE=$1
53
54 ip netns delete $NODE
55}
56
57netjail_node_link_bridge() {
58 NODE=$1
59 BRIDGE=$2
60 ADDRESS=$3
61 MASK=$4
62
63 LINK_IF="$NODE-$BRIDGE-0"
64 LINK_BR="$NODE-$BRIDGE-1"
65
66 ip link add $LINK_IF type veth peer name $LINK_BR
67 ip link set $LINK_IF netns $NODE
68 ip link set $LINK_BR master $BRIDGE
69
70 ip -n $NODE addr add "$ADDRESS/$MASK" dev $LINK_IF
71 ip -n $NODE link set $LINK_IF up
72 ip -n $NODE link set up dev lo
73
74 ip link set $LINK_BR up
75}
76
77netjail_node_add_nat() {
78 NODE=$1
79 ADDRESS=$2
80 MASK=$3
81
82 ip netns exec $NODE iptables -t nat -A POSTROUTING -s "$ADDRESS/$MASK" -j MASQUERADE
83}
84
85netjail_node_add_default() {
86 NODE=$1
87 ADDRESS=$2
88
89 ip -n $NODE route add default via $ADDRESS
90}
91
92netjail_node_exec() {
93 JAILOR=${SUDO_USER:?must run in sudo}
94 NODE=$1
95 FD_IN=$2
96 FD_OUT=$3
97 shift 3
98
99 ip netns exec $NODE sudo -u $JAILOR -- $@ 1>& $FD_OUT 0<& $FD_IN
100}
101
102netjail_node_exec_without_fds() {
103 JAILOR=${SUDO_USER:?must run in sudo}
104 NODE=$1
105 shift 1
106
107 ip netns exec $NODE sudo -u $JAILOR -- $@
108}
109
110netjail_node_exec_without_fds_and_sudo() {
111 NODE=$1
112 shift 1
113
114 ip netns exec $NODE $@
115}
116
diff --git a/src/testing/netjail_exec.sh b/src/testing/netjail_exec.sh
new file mode 100755
index 000000000..17a7caaac
--- /dev/null
+++ b/src/testing/netjail_exec.sh
@@ -0,0 +1,16 @@
1#!/bin/sh
2. "./../testing/netjail_core.sh"
3
4set -eu
5set -x
6
7export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
8
9M=$1
10N=$2
11
12NODE=$(netjail_print_name "N" $N $M)
13
14
15
16netjail_node_exec_without_fds_and_sudo $NODE $3 $4 $5 $1 $2
diff --git a/src/testing/netjail_start.sh b/src/testing/netjail_start.sh
new file mode 100755
index 000000000..0984a3c42
--- /dev/null
+++ b/src/testing/netjail_start.sh
@@ -0,0 +1,52 @@
1#!/bin/sh
2. "./../testing/netjail_core.sh"
3
4set -eu
5set -x
6
7export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
8
9LOCAL_M=$1
10GLOBAL_N=$2
11
12# TODO: stunserver? ..and globally known peer?
13
14shift 2
15
16LOCAL_GROUP="192.168.15"
17GLOBAL_GROUP="92.68.150"
18
19NETWORK_NET=$(netjail_print_name "n" $GLOBAL_N $LOCAL_M)
20
21netjail_bridge $NETWORK_NET
22
23for N in $(seq $GLOBAL_N); do
24 ROUTER=$(netjail_print_name "R" $N)
25
26 netjail_node $ROUTER
27 netjail_node_link_bridge $ROUTER $NETWORK_NET "$GLOBAL_GROUP.$N" 24
28
29 ROUTER_NET=$(netjail_print_name "r" $N)
30
31 netjail_bridge $ROUTER_NET
32
33 for M in $(seq $LOCAL_M); do
34 NODE=$(netjail_print_name "N" $N $M)
35
36 netjail_node $NODE
37 netjail_node_link_bridge $NODE $ROUTER_NET "$LOCAL_GROUP.$M" 24
38 done
39
40 ROUTER_ADDR="$LOCAL_GROUP.$(($LOCAL_M+1))"
41
42 netjail_node_link_bridge $ROUTER $ROUTER_NET $ROUTER_ADDR 24
43 netjail_node_add_nat $ROUTER $ROUTER_ADDR 24
44
45 for M in $(seq $LOCAL_M); do
46 NODE=$(netjail_print_name "N" $N $M)
47
48 netjail_node_add_default $NODE $ROUTER_ADDR
49 done
50done
51
52
diff --git a/src/testing/netjail_stop.sh b/src/testing/netjail_stop.sh
new file mode 100755
index 000000000..08f68cf7f
--- /dev/null
+++ b/src/testing/netjail_stop.sh
@@ -0,0 +1,26 @@
1#!/bin/sh
2. "./../testing/netjail_core.sh"
3
4set -eu
5set -x
6
7export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
8
9LOCAL_M=$1
10GLOBAL_N=$2
11NETWORK_NET=$(netjail_print_name "n" $GLOBAL_N $LOCAL_M)
12
13shift 2
14
15for N in $(seq $GLOBAL_N); do
16 for M in $(seq $LOCAL_M); do
17 netjail_node_clear $(netjail_print_name "N" $N $M)
18 done
19
20 netjail_bridge_clear $(netjail_print_name "r" $N)
21 netjail_node_clear $(netjail_print_name "R" $N)
22done
23
24netjail_bridge_clear $NETWORK_NET
25
26echo "Done"
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..444272fcd
--- /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) 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 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..e9d3f0ed3
--- /dev/null
+++ b/src/testing/testing_api_cmd_block_until_all_peers_started.c
@@ -0,0 +1,139 @@
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
35/**
36 * Struct with information for callbacks.
37 *
38 */
39struct BlockState
40{
41 /**
42 * Flag to indicate if all peers have started.
43 *
44 */
45 unsigned int *all_peers_started;
46};
47
48
49/**
50 * Trait function of this cmd does nothing.
51 *
52 */
53static int
54block_until_all_peers_started_traits (void *cls,
55 const void **ret,
56 const char *trait,
57 unsigned int index)
58{
59 return GNUNET_OK;
60}
61
62
63/**
64 * The cleanup function of this cmd frees resources the cmd allocated.
65 *
66 */
67static void
68block_until_all_peers_started_cleanup (void *cls,
69 const struct GNUNET_TESTING_Command *cmd)
70{
71 struct BlockState *bs = cls;
72
73 GNUNET_free (bs);
74}
75
76
77/**
78 * This function does nothing but to start the cmd.
79 *
80 */
81static void
82block_until_all_peers_started_run (void *cls,
83 const struct GNUNET_TESTING_Command *cmd,
84 struct GNUNET_TESTING_Interpreter *is)
85{
86 LOG (GNUNET_ERROR_TYPE_DEBUG,
87 "block_until_all_peers_started_run!\n");
88}
89
90
91/**
92 * Function to check if BlockState#all_peers_started is GNUNET_YES. In that case interpreter_next will be called.
93 *
94 */
95static int
96block_until_all_peers_started_finish (void *cls,
97 GNUNET_SCHEDULER_TaskCallback cont,
98 void *cont_cls)
99{
100 struct BlockState *bs = cls;
101 unsigned int *ret = bs->all_peers_started;
102
103 if (GNUNET_YES == *ret)
104 {
105 cont (cont_cls);
106 }
107
108 return *ret;
109}
110
111
112/**
113 * Create command.
114 *
115 * @param label name for command.
116 * @param all_peers_started Flag which will be set from outside.
117 * @return command.
118 */
119struct GNUNET_TESTING_Command
120GNUNET_TESTING_cmd_block_until_all_peers_started (const char *label,
121 unsigned int *
122 all_peers_started)
123{
124 struct BlockState *bs;
125
126 bs = GNUNET_new (struct BlockState);
127 bs->all_peers_started = all_peers_started;
128
129 struct GNUNET_TESTING_Command cmd = {
130 .cls = bs,
131 .label = label,
132 .run = &block_until_all_peers_started_run,
133 .finish = &block_until_all_peers_started_finish,
134 .cleanup = &block_until_all_peers_started_cleanup,
135 .traits = &block_until_all_peers_started_traits
136 };
137
138 return cmd;
139}
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..383de4c10
--- /dev/null
+++ b/src/testing/testing_api_cmd_local_test_finished.c
@@ -0,0 +1,151 @@
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
36
37/**
38 * Struct to hold information for callbacks.
39 *
40 */
41struct LocalFinishedState
42{
43 /**
44 * Callback to write messages to the master loop.
45 *
46 */
47 TESTING_CMD_HELPER_write_cb write_message;
48
49 /**
50 * The message send back to the master loop.
51 *
52 */
53 struct GNUNET_CMDS_LOCAL_FINISHED *reply;
54};
55
56
57/**
58 * Trait function of this cmd does nothing.
59 *
60 */
61static int
62local_test_finished_traits (void *cls,
63 const void **ret,
64 const char *trait,
65 unsigned int index)
66{
67 return GNUNET_OK;
68}
69
70
71/**
72 * The cleanup function of this cmd frees resources the cmd allocated.
73 *
74 */
75static void
76local_test_finished_cleanup (void *cls,
77 const struct GNUNET_TESTING_Command *cmd)
78{
79 struct LocalFinishedState *lfs = cls;
80
81 GNUNET_free (lfs->reply);
82 GNUNET_free (lfs);
83}
84
85
86/**
87 * This function sends a GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED message to the master loop.
88 *
89 */
90static void
91local_test_finished_run (void *cls,
92 const struct GNUNET_TESTING_Command *cmd,
93 struct GNUNET_TESTING_Interpreter *is)
94{
95 struct LocalFinishedState *lfs = cls;
96
97 struct GNUNET_CMDS_LOCAL_FINISHED *reply;
98 size_t msg_length;
99
100 msg_length = sizeof(struct GNUNET_CMDS_LOCAL_FINISHED);
101 reply = GNUNET_new (struct GNUNET_CMDS_LOCAL_FINISHED);
102 reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED);
103 reply->header.size = htons ((uint16_t) msg_length);
104 lfs->reply = reply;
105 lfs->write_message ((struct GNUNET_MessageHeader *) reply, msg_length);
106}
107
108
109/**
110 * This finish function will stop the local loop without shutting down the scheduler, because we do not call the continuation, which is the interpreter_next method.
111 *
112 */
113static int
114local_test_finished_finish (void *cls,
115 GNUNET_SCHEDULER_TaskCallback cont,
116 void *cont_cls)
117{
118 LOG (GNUNET_ERROR_TYPE_DEBUG,
119 "Stopping local loop\n");
120 return GNUNET_YES;
121}
122
123
124/**
125 * Create command.
126 *
127 * @param label name for command.
128 * @param write_message Callback to write messages to the master loop.
129 * @return command.
130 */
131struct GNUNET_TESTING_Command
132GNUNET_TESTING_cmd_local_test_finished (const char *label,
133 TESTING_CMD_HELPER_write_cb
134 write_message)
135{
136 struct LocalFinishedState *lfs;
137
138 lfs = GNUNET_new (struct LocalFinishedState);
139 lfs->write_message = write_message;
140
141 struct GNUNET_TESTING_Command cmd = {
142 .cls = lfs,
143 .label = label,
144 .run = &local_test_finished_run,
145 .finish = &local_test_finished_finish,
146 .cleanup = &local_test_finished_cleanup,
147 .traits = &local_test_finished_traits
148 };
149
150 return cmd;
151}
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..536b356a6
--- /dev/null
+++ b/src/testing/testing_api_cmd_netjail_start.c
@@ -0,0 +1,229 @@
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
32/**
33 * Struct to hold information for callbacks.
34 *
35 */
36struct NetJailState
37{
38 // Child Wait handle
39 struct GNUNET_ChildWaitHandle *cwh;
40
41 // Number of local nodes in each namespace.
42 char *local_m;
43
44 // The number of namespaces.
45 char *global_n;
46
47 /**
48 * The process id of the start script.
49 */
50 struct GNUNET_OS_Process *start_proc;
51
52 // Flag indication if the script finished.
53 unsigned int finished;
54};
55
56
57/**
58 * The cleanup function of this cmd frees resources the cmd allocated.
59 *
60 */
61static void
62netjail_start_cleanup (void *cls,
63 const struct GNUNET_TESTING_Command *cmd)
64{
65 struct NetJailState *ns = cls;
66
67 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
68 "netjail_start_cleanup!\n");
69
70 if (NULL != ns->cwh)
71 {
72 GNUNET_wait_child_cancel (ns->cwh);
73 ns->cwh = NULL;
74 }
75 if (NULL != ns->start_proc)
76 {
77 GNUNET_assert (0 ==
78 GNUNET_OS_process_kill (ns->start_proc,
79 SIGKILL));
80 GNUNET_assert (GNUNET_OK ==
81 GNUNET_OS_process_wait (ns->start_proc));
82 GNUNET_OS_process_destroy (ns->start_proc);
83 ns->start_proc = NULL;
84 }
85 GNUNET_free (ns);
86}
87
88
89/**
90 * Trait function of this cmd does nothing.
91 *
92 */
93static int
94netjail_start_traits (void *cls,
95 const void **ret,
96 const char *trait,
97 unsigned int index)
98{
99 return GNUNET_OK;
100}
101
102
103/**
104 * Callback which will be called if the setup script finished.
105 *
106 */
107static void
108child_completed_callback (void *cls,
109 enum GNUNET_OS_ProcessStatusType type,
110 long unsigned int exit_code)
111{
112 struct NetJailState *ns = cls;
113
114 if (0 == exit_code)
115 {
116 ns->finished = GNUNET_YES;
117 }
118 else
119 {
120 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
121 "Child completed with an error!\n");
122 ns->finished = GNUNET_SYSERR;
123 }
124 GNUNET_OS_process_destroy (ns->start_proc);
125 ns->start_proc = NULL;
126}
127
128
129
130/**
131* The run method starts the script which setup the network namespaces.
132*
133* @param cls closure.
134* @param cmd CMD being run.
135* @param is interpreter state.
136*/
137static void
138netjail_start_run (void *cls,
139 const struct GNUNET_TESTING_Command *cmd,
140 struct GNUNET_TESTING_Interpreter *is)
141{
142 struct NetJailState *ns = cls;
143 char *const script_argv[] = {NETJAIL_START_SCRIPT,
144 ns->local_m,
145 ns->global_n,
146 NULL};
147 unsigned int helper_check = GNUNET_OS_check_helper_binary (
148 NETJAIL_START_SCRIPT,
149 GNUNET_YES,
150 NULL);
151
152 if (GNUNET_NO == helper_check)
153 {
154 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
155 "No SUID for %s!\n",
156 NETJAIL_START_SCRIPT);
157 GNUNET_TESTING_interpreter_fail ();
158 }
159 else if (GNUNET_NO == helper_check)
160 {
161 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
162 "%s not found!\n",
163 NETJAIL_START_SCRIPT);
164 GNUNET_TESTING_interpreter_fail ();
165 }
166
167 ns->start_proc = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ERR,
168 NULL,
169 NULL,
170 NULL,
171 NETJAIL_START_SCRIPT,
172 script_argv);
173
174 ns->cwh = GNUNET_wait_child (ns->start_proc,
175 &child_completed_callback,
176 ns);
177 GNUNET_break (NULL != ns->cwh);
178}
179
180
181/**
182 * This function checks the flag NetJailState#finished, if this cmd finished.
183 *
184 */
185static int
186netjail_start_finish (void *cls,
187 GNUNET_SCHEDULER_TaskCallback cont,
188 void *cont_cls)
189{
190 struct NetJailState *ns = cls;
191
192 if (ns->finished)
193 {
194 cont (cont_cls);
195 }
196 return ns->finished;
197}
198
199/**
200 * Create command.
201 *
202 * @param label name for command.
203 * @param local_m Number of local nodes in each namespace.
204 * @param global_n The number of namespaces.
205 * @return command.
206 */
207struct GNUNET_TESTING_Command
208GNUNET_TESTING_cmd_netjail_start (const char *label,
209 char *local_m,
210 char *global_n)
211{
212 struct NetJailState *ns;
213
214 ns = GNUNET_new (struct NetJailState);
215 ns->local_m = local_m;
216 ns->global_n = global_n;
217 ns->finished = GNUNET_NO;
218
219 struct GNUNET_TESTING_Command cmd = {
220 .cls = ns,
221 .label = label,
222 .run = &netjail_start_run,
223 .finish = &netjail_start_finish,
224 .cleanup = &netjail_start_cleanup,
225 .traits = &netjail_start_traits
226 };
227
228 return cmd;
229}
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..0fe0541b0
--- /dev/null
+++ b/src/testing/testing_api_cmd_netjail_start_testsystem.c
@@ -0,0 +1,630 @@
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
32/**
33 * Struct to store messages send/received by the helper into a DLL
34 *
35 */
36struct HelperMessage
37{
38
39 /**
40 * Kept in a DLL.
41 */
42 struct HelperMessage *next;
43
44 /**
45 * Kept in a DLL.
46 */
47 struct HelperMessage *prev;
48
49 /**
50 * Size of the original message.
51 */
52 uint16_t bytes_msg;
53
54 /* Followed by @e bytes_msg of msg.*/
55};
56
57
58/**
59 * Struct to store information handed over to callbacks.
60 *
61 */
62struct NetJailState
63{
64 /**
65 * Pointer to the return value of the test.
66 *
67 */
68 unsigned int *rv;
69
70 /**
71 * Head of the DLL which stores messages received by the helper.
72 *
73 */
74 struct HelperMessage *hp_messages_head;
75
76 /**
77 * Tail of the DLL which stores messages received by the helper.
78 *
79 */
80 struct HelperMessage *hp_messages_tail;
81
82 /**
83 * Array with handles of helper processes.
84 */
85 struct GNUNET_HELPER_Handle **helper;
86
87 /**
88 * Size of the array NetJailState#helper.
89 *
90 */
91 unsigned int n_helper;
92
93 /**
94 * Number of nodes in a network namespace. //TODO make this a unsigned int
95 *
96 */
97 char *local_m;
98
99 /**
100 * Number of network namespaces. //TODO make this a unsigned int
101 *
102 */
103 char *global_n;
104
105 /**
106 * The send handle for the helper
107 */
108 struct GNUNET_HELPER_SendHandle **shandle;
109
110 /**
111 * Size of the array NetJailState#shandle.
112 *
113 */
114 unsigned int n_shandle;
115
116 /**
117 * The messages send to the helper.
118 */
119 struct GNUNET_MessageHeader **msg;
120
121 /**
122 * Size of the array NetJailState#msg.
123 *
124 */
125 unsigned int n_msg;
126
127 /**
128 * Number of test environments started.
129 *
130 */
131 unsigned int number_of_testsystems_started;
132
133 /**
134 * Number of peers started.
135 *
136 */
137 unsigned int number_of_peers_started;
138
139 /**
140 * Number of local tests finished.
141 *
142 */
143 unsigned int number_of_local_test_finished;
144
145 /**
146 * Name of the test case plugin the helper will load.
147 *
148 */
149 char *plugin_name;
150
151 /**
152 * HEAD of the DLL containing TestingSystemCount.
153 *
154 */
155 struct TestingSystemCount *tbcs_head;
156
157 /**
158 * TAIL of the DLL containing TestingSystemCount.
159 *
160 */
161 struct TestingSystemCount *tbcs_tail;
162};
163
164/**
165 * Struct containing the number of the test environment and the NetJailState which
166 * will be handed to callbacks specific to a test environment.
167 */
168struct TestingSystemCount
169{
170 /**
171 * Kept in a DLL.
172 */
173 struct TestingSystemCount *next;
174
175 /**
176 * Kept in a DLL.
177 */
178 struct TestingSystemCount *prev;
179
180 /**
181 * The number of the test environment.
182 *
183 */
184 unsigned int count;
185
186 /**
187 * Struct to store information handed over to callbacks.
188 *
189 */
190 struct NetJailState *ns;
191};
192
193/**
194* Code to clean up resource this cmd used.
195*
196* @param cls closure
197* @param cmd current CMD being cleaned up.
198*/
199static void
200netjail_exec_cleanup (void *cls,
201 const struct GNUNET_TESTING_Command *cmd)
202{
203 struct NetJailState *ns = cls;
204 struct HelperMessage *message_pos;
205 struct TestingSystemCount *tbc_pos;
206
207 while (NULL != (message_pos = ns->hp_messages_head))
208 {
209 GNUNET_CONTAINER_DLL_remove (ns->hp_messages_head,
210 ns->hp_messages_tail,
211 message_pos);
212 GNUNET_free (message_pos);
213 }
214 while (NULL != (tbc_pos = ns->tbcs_head))
215 {
216 GNUNET_CONTAINER_DLL_remove (ns->tbcs_head,
217 ns->tbcs_tail,
218 tbc_pos);
219 GNUNET_free (tbc_pos);
220 }
221 GNUNET_free (ns);
222}
223
224
225/**
226 * This function prepares an array with traits.
227 *
228 */
229static int
230netjail_exec_traits (void *cls,
231 const void **ret,
232 const char *trait,
233 unsigned int index)
234{
235 struct NetJailState *ns = cls;
236 struct GNUNET_HELPER_Handle **helper = ns->helper;
237 struct HelperMessage *hp_messages_head = ns->hp_messages_head;
238
239
240 struct GNUNET_TESTING_Trait traits[] = {
241 {
242 .index = 0,
243 .trait_name = "helper_handles",
244 .ptr = (const void *) helper,
245 },
246 {
247 .index = 1,
248 .trait_name = "hp_msgs_head",
249 .ptr = (const void *) hp_messages_head,
250 },
251 GNUNET_TESTING_trait_end ()
252 };
253
254 return GNUNET_TESTING_get_trait (traits,
255 ret,
256 trait,
257 index);
258}
259
260
261/**
262 * Offer handles to testing cmd helper from trait
263 *
264 * @param cmd command to extract the message from.
265 * @param pt pointer to message.
266 * @return #GNUNET_OK on success.
267 */
268int
269GNUNET_TESTING_get_trait_helper_handles (const struct
270 GNUNET_TESTING_Command *cmd,
271 struct GNUNET_HELPER_Handle ***helper)
272{
273 return cmd->traits (cmd->cls,
274 (const void **) helper,
275 "helper_handles",
276 (unsigned int) 0);
277}
278
279
280/**
281 * Offer messages received via testing cmd helper from trait
282 *
283 * @param cmd command to extract the message from.
284 * @param pt pointer to message.
285 * @return #GNUNET_OK on success.
286 */
287int
288GNUNET_TESTING_get_trait_helper_messages (const struct
289 GNUNET_TESTING_Command *cmd,
290 struct HelperMessage ***
291 hp_messages_head)
292{
293 return cmd->traits (cmd->cls,
294 (const void **) hp_messages_head,
295 "hp_msgs_head",
296 (unsigned int) 1);
297}
298
299
300/**
301 * Continuation function from GNUNET_HELPER_send()
302 *
303 * @param cls closure
304 * @param result GNUNET_OK on success,
305 * GNUNET_NO if helper process died
306 * GNUNET_SYSERR during GNUNET_HELPER_stop
307 */
308static void
309clear_msg (void *cls, int result)
310{
311 struct TestingSystemCount *tbc = cls;
312 struct NetJailState *ns = tbc->ns;
313
314 GNUNET_assert (NULL != ns->shandle[tbc->count - 1]);
315 ns->shandle[tbc->count - 1] = NULL;
316 GNUNET_free (ns->msg[tbc->count - 1]);
317 ns->msg[tbc->count - 1] = NULL;
318}
319
320
321/**
322 * Functions with this signature are called whenever a
323 * complete message is received by the tokenizer.
324 *
325 * Do not call GNUNET_SERVER_mst_destroy in callback
326 *
327 * @param cls closure
328 * @param client identification of the client
329 * @param message the actual message
330 *
331 * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
332 */
333static int
334helper_mst (void *cls, const struct GNUNET_MessageHeader *message)
335{
336 struct TestingSystemCount *tbc = cls;
337 struct NetJailState *ns = tbc->ns;
338 struct HelperMessage *hp_msg;
339
340 if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY == ntohs (message->type))
341 {
342 ns->number_of_testsystems_started++;
343 }
344 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED == ntohs (
345 message->type))
346 {
347 ns->number_of_peers_started++;
348 }
349 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED == ntohs (
350 message->type))
351 {
352 ns->number_of_local_test_finished++;
353 }
354 else
355 {
356 hp_msg = GNUNET_new (struct HelperMessage);
357 hp_msg->bytes_msg = message->size;
358 memcpy (&hp_msg[1], message, message->size);
359 GNUNET_CONTAINER_DLL_insert (ns->hp_messages_head, ns->hp_messages_tail,
360 hp_msg);
361 }
362
363 return GNUNET_OK;
364}
365
366
367/**
368 * Callback called if there was an exception during execution of the helper.
369 *
370 */
371static void
372exp_cb (void *cls)
373{
374 struct NetJailState *ns = cls;
375 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called exp_cb.\n");
376 *ns->rv = 1;
377}
378
379
380/**
381 * Function to initialize a init message for the helper.
382 *
383 * @param m_char The actual node in a namespace. //TODO Change this to unsigned int
384 * @param n_char The actual namespace. //TODO Change this to unsigned int
385 * @param plugin_name Name of the test case plugin the helper will load.
386 *
387 */
388static struct GNUNET_CMDS_HelperInit *
389create_helper_init_msg_ (char *m_char,
390 char *n_char,
391 const char *plugin_name)
392{
393 struct GNUNET_CMDS_HelperInit *msg;
394 uint16_t plugin_name_len;
395 uint16_t msg_size;
396
397 GNUNET_assert (NULL != plugin_name);
398 plugin_name_len = strlen (plugin_name);
399 msg_size = sizeof(struct GNUNET_CMDS_HelperInit) + plugin_name_len;
400 msg = GNUNET_malloc (msg_size);
401 msg->header.size = htons (msg_size);
402 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT);
403 msg->plugin_name_size = htons (plugin_name_len);
404 GNUNET_memcpy ((char *) &msg[1],
405 plugin_name,
406 plugin_name_len);
407 return msg;
408}
409
410
411/**
412 * Function which start a single helper process.
413 *
414 */
415static void
416start_helper (struct NetJailState *ns, struct
417 GNUNET_CONFIGURATION_Handle *config,
418 char *m_char,
419 char *n_char)
420{
421 struct GNUNET_HELPER_Handle *helper;
422 struct GNUNET_CMDS_HelperInit *msg;
423 struct TestingSystemCount *tbc;
424 char *const script_argv[] = {NETJAIL_EXEC_SCRIPT,
425 m_char,
426 n_char,
427 GNUNET_OS_get_libexec_binary_path (
428 HELPER_CMDS_BINARY),
429 ns->global_n,
430 ns->local_m,
431 NULL};
432 unsigned int m = atoi (m_char);
433 unsigned int n = atoi (n_char);
434 unsigned int helper_check = GNUNET_OS_check_helper_binary (
435 NETJAIL_EXEC_SCRIPT,
436 GNUNET_YES,
437 NULL);
438
439 tbc = GNUNET_new (struct TestingSystemCount);
440 tbc->ns = ns;
441 tbc->count = (n - 1) * atoi (ns->local_m) + m;
442
443 GNUNET_CONTAINER_DLL_insert (ns->tbcs_head, ns->tbcs_tail,
444 tbc);
445
446
447 if (GNUNET_NO == helper_check)
448 {
449 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
450 "No SUID for %s!\n",
451 NETJAIL_EXEC_SCRIPT);
452 *ns->rv = 1;
453 }
454 else if (GNUNET_NO == helper_check)
455 {
456 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
457 "%s not found!\n",
458 NETJAIL_EXEC_SCRIPT);
459 *ns->rv = 1;
460 }
461
462 GNUNET_array_append (ns->helper, ns->n_helper, GNUNET_HELPER_start (
463 GNUNET_YES,
464 NETJAIL_EXEC_SCRIPT,
465 script_argv,
466 &helper_mst,
467 &exp_cb,
468 tbc));
469
470 helper = ns->helper[tbc->count - 1];
471
472 msg = create_helper_init_msg_ (m_char,
473 n_char,
474 ns->plugin_name);
475 GNUNET_array_append (ns->msg, ns->n_msg, &msg->header);
476
477 GNUNET_array_append (ns->shandle, ns->n_shandle, GNUNET_HELPER_send (
478 helper,
479 &msg->header,
480 GNUNET_NO,
481 &clear_msg,
482 tbc));
483
484 if (NULL == ns->shandle[tbc->count - 1])
485 {
486 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
487 "Send handle is NULL!\n");
488 GNUNET_free (msg);
489 *ns->rv = 1;
490 }
491}
492
493
494/**
495* This function starts a helper process for each node.
496*
497* @param cls closure.
498* @param cmd CMD being run.
499* @param is interpreter state.
500*/
501static void
502netjail_exec_run (void *cls,
503 const struct GNUNET_TESTING_Command *cmd,
504 struct GNUNET_TESTING_Interpreter *is)
505{
506 char str_m[12];
507 char str_n[12];
508 struct NetJailState *ns = cls;
509 struct GNUNET_CONFIGURATION_Handle *config =
510 GNUNET_CONFIGURATION_create ();
511
512 for (int i = 1; i <= atoi (ns->global_n); i++)
513 {
514 for (int j = 1; j <= atoi (ns->local_m); j++)
515 {
516 sprintf (str_n, "%d", i);
517 sprintf (str_m, "%d", j);
518 start_helper (ns, config,
519 str_m,
520 str_n);
521 }
522 }
523}
524
525
526/**
527 * This function checks on three different information.
528 *
529 * 1. Did all helpers start. This is only logged.
530 * 2. Did all peer start.
531 * In this case a GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED is send to all peers.
532 * 3. Did all peers finished the test case. In this case interpreter_next will be called.
533 *
534 */
535static int
536netjail_start_finish (void *cls,
537 GNUNET_SCHEDULER_TaskCallback cont,
538 void *cont_cls)
539{
540 unsigned int ret = GNUNET_NO;
541 struct NetJailState *ns = cls;
542 unsigned int total_number = atoi (ns->local_m) * atoi (ns->global_n);
543 struct GNUNET_CMDS_ALL_PEERS_STARTED *reply;
544 size_t msg_length;
545 struct GNUNET_HELPER_Handle *helper;
546 struct TestingSystemCount *tbc;
547
548 if (ns->number_of_local_test_finished == total_number)
549 {
550 ret = GNUNET_YES;
551 cont (cont_cls);
552 }
553
554 if (ns->number_of_testsystems_started == total_number)
555 {
556 ns->number_of_testsystems_started = 0;
557 }
558
559 if (ns->number_of_peers_started == total_number)
560 {
561 for (int i = 1; i <= atoi (ns->global_n); i++)
562 {
563 for (int j = 1; j <= atoi (ns->local_m); j++)
564 {
565 tbc = GNUNET_new (struct TestingSystemCount);
566 tbc->ns = ns;
567 // 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.
568 tbc->count = (i - 1) * atoi (ns->local_m) + j + total_number;
569
570 helper = ns->helper[tbc->count - 1 - total_number];
571 msg_length = sizeof(struct GNUNET_CMDS_ALL_PEERS_STARTED);
572 reply = GNUNET_new (struct GNUNET_CMDS_ALL_PEERS_STARTED);
573 reply->header.type = htons (
574 GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED);
575 reply->header.size = htons ((uint16_t) msg_length);
576
577 GNUNET_array_append (ns->msg, ns->n_msg, &reply->header);
578
579 struct GNUNET_HELPER_SendHandle *sh = GNUNET_HELPER_send (
580 helper,
581 &reply->header,
582 GNUNET_NO,
583 &clear_msg,
584 tbc);
585
586 GNUNET_array_append (ns->shandle, ns->n_shandle, sh);
587 }
588 }
589 ns->number_of_peers_started = 0;
590 }
591 return ret;
592}
593
594
595/**
596 * Create command.
597 *
598 * @param label Name for the command.
599 * @param local_m Number of nodes in a network namespace. //TODO make this a unsigned int
600 * @param global_n Number of network namespaces. //TODO make this a unsigned int
601 * @param plugin_name Name of the test case plugin the helper will load.
602 * @param rv Pointer to the return value of the test.
603 * @return command.
604 */
605struct GNUNET_TESTING_Command
606GNUNET_TESTING_cmd_netjail_start_testing_system (const char *label,
607 char *local_m,
608 char *global_n,
609 char *plugin_name,
610 unsigned int *rv)
611{
612 struct NetJailState *ns;
613
614 ns = GNUNET_new (struct NetJailState);
615 ns->local_m = local_m;
616 ns->global_n = global_n;
617 ns->plugin_name = plugin_name;
618 ns->rv = rv;
619
620 struct GNUNET_TESTING_Command cmd = {
621 .cls = ns,
622 .label = label,
623 .run = &netjail_exec_run,
624 .finish = &netjail_start_finish,
625 .cleanup = &netjail_exec_cleanup,
626 .traits = &netjail_exec_traits
627 };
628
629 return cmd;
630}
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..99084d9af
--- /dev/null
+++ b/src/testing/testing_api_cmd_netjail_stop.c
@@ -0,0 +1,225 @@
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
33// Child Wait handle
34struct GNUNET_ChildWaitHandle *cwh;
35
36/**
37 * Struct to hold information for callbacks.
38 *
39 */
40struct NetJailState
41{
42 // Number of local nodes in each namespace.
43 char *local_m;
44
45 // The number of namespaces.
46 char *global_n;
47
48 /**
49 * The process id of the start script.
50 */
51 struct GNUNET_OS_Process *stop_proc;
52
53 // Flag indication if the script finished.
54 unsigned int finished;
55};
56
57
58/**
59 * The cleanup function of this cmd frees resources the cmd allocated.
60 *
61 */
62static void
63netjail_stop_cleanup (void *cls,
64 const struct GNUNET_TESTING_Command *cmd)
65{
66 struct NetJailState *ns = cls;
67
68 if (NULL != cwh)
69 {
70 GNUNET_wait_child_cancel (cwh);
71 cwh = NULL;
72 }
73 if (NULL != ns->stop_proc)
74 {
75 GNUNET_assert (0 ==
76 GNUNET_OS_process_kill (ns->stop_proc,
77 SIGKILL));
78 GNUNET_assert (GNUNET_OK ==
79 GNUNET_OS_process_wait (ns->stop_proc));
80 GNUNET_OS_process_destroy (ns->stop_proc);
81 ns->stop_proc = NULL;
82 }
83}
84
85
86/**
87 * Trait function of this cmd does nothing.
88 *
89 */
90static int
91netjail_stop_traits (void *cls,
92 const void **ret,
93 const char *trait,
94 unsigned int index)
95{
96 return GNUNET_OK;
97}
98
99
100/**
101 * Callback which will be called if the setup script finished.
102 *
103 */
104static void
105child_completed_callback (void *cls,
106 enum GNUNET_OS_ProcessStatusType type,
107 long unsigned int exit_code)
108{
109 struct NetJailState *ns = cls;
110
111 cwh = NULL;
112 if (0 == exit_code)
113 {
114 ns->finished = GNUNET_YES;
115 }
116 else
117 {
118 ns->finished = GNUNET_SYSERR;
119 }
120 GNUNET_OS_process_destroy (ns->stop_proc);
121 ns->stop_proc = NULL;
122}
123
124
125/**
126* The run method starts the script which deletes the network namespaces.
127*
128* @param cls closure.
129* @param cmd CMD being run.
130* @param is interpreter state.
131*/
132static void
133netjail_stop_run (void *cls,
134 const struct GNUNET_TESTING_Command *cmd,
135 struct GNUNET_TESTING_Interpreter *is)
136{
137 struct NetJailState *ns = cls;
138 char *const script_argv[] = {NETJAIL_STOP_SCRIPT,
139 ns->local_m,
140 ns->global_n,
141 NULL};
142 unsigned int helper_check = GNUNET_OS_check_helper_binary (
143 NETJAIL_STOP_SCRIPT,
144 GNUNET_YES,
145 NULL);
146
147 if (GNUNET_NO == helper_check)
148 {
149 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
150 "No SUID for %s!\n",
151 NETJAIL_STOP_SCRIPT);
152 GNUNET_TESTING_interpreter_fail ();
153 }
154 else if (GNUNET_NO == helper_check)
155 {
156 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
157 "%s not found!\n",
158 NETJAIL_STOP_SCRIPT);
159 GNUNET_TESTING_interpreter_fail ();
160 }
161
162 ns->stop_proc = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ERR,
163 NULL,
164 NULL,
165 NULL,
166 NETJAIL_STOP_SCRIPT,
167 script_argv);
168
169 cwh = GNUNET_wait_child (ns->stop_proc,
170 &child_completed_callback,
171 ns);
172 GNUNET_break (NULL != cwh);
173
174}
175
176
177/**
178 * This function checks the flag NetJailState#finished, if this cmd finished.
179 *
180 */
181static int
182netjail_stop_finish (void *cls,
183 GNUNET_SCHEDULER_TaskCallback cont,
184 void *cont_cls)
185{
186 struct NetJailState *ns = cls;
187
188 if (ns->finished)
189 {
190 cont (cont_cls);
191 }
192 return ns->finished;
193}
194
195
196/**
197 * Create command.
198 *
199 * @param label name for command.
200 * @param local_m Number of local nodes in each namespace.
201 * @param global_n The number of namespaces.
202 * @return command.
203 */
204struct GNUNET_TESTING_Command
205GNUNET_TESTING_cmd_netjail_stop (const char *label,
206 char *local_m,
207 char *global_n)
208{
209 struct NetJailState *ns;
210
211 ns = GNUNET_new (struct NetJailState);
212 ns->local_m = local_m;
213 ns->global_n = global_n;
214
215 struct GNUNET_TESTING_Command cmd = {
216 .cls = ns,
217 .label = label,
218 .run = &netjail_stop_run,
219 .finish = &netjail_stop_finish,
220 .cleanup = &netjail_stop_cleanup,
221 .traits = &netjail_stop_traits
222 };
223
224 return cmd;
225}
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..0ae82a26a
--- /dev/null
+++ b/src/testing/testing_api_cmd_netjail_stop_testsystem.c
@@ -0,0 +1,143 @@
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
31/**
32 * Struct to store information handed over to callbacks.
33 *
34 */
35struct StopHelperState
36{
37
38 const char *helper_start_label;
39
40 /**
41 * The process handle
42 */
43 struct GNUNET_HELPER_Handle **helper;
44
45 char *local_m;
46
47 char *global_n;
48};
49
50
51/**
52* Code to clean up resource this cmd used.
53*
54* @param cls closure
55* @param cmd current CMD being cleaned up.
56*/
57static void
58stop_testing_system_cleanup (void *cls,
59 const struct GNUNET_TESTING_Command *cmd)
60{
61
62}
63
64
65/**
66 * Trait function of this cmd does nothing.
67 *
68 */
69static int
70stop_testing_system_traits (void *cls,
71 const void **ret,
72 const char *trait,
73 unsigned int index)
74{
75 return GNUNET_OK;
76}
77
78
79/**
80* This function stops the helper process for each node.
81*
82* @param cls closure.
83* @param cmd CMD being run.
84* @param is interpreter state.
85*/
86static void
87stop_testing_system_run (void *cls,
88 const struct GNUNET_TESTING_Command *cmd,
89 struct GNUNET_TESTING_Interpreter *is)
90{
91 struct StopHelperState *shs = cls;
92 struct GNUNET_HELPER_Handle **helper;
93 const struct GNUNET_TESTING_Command *start_helper_cmd;
94
95 start_helper_cmd = GNUNET_TESTING_interpreter_lookup_command (
96 shs->helper_start_label);
97 GNUNET_TESTING_get_trait_helper_handles (start_helper_cmd,
98 &helper);
99
100 for (int i = 1; i <= atoi (shs->global_n); i++)
101 {
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 * @param helper_start_label label of the cmd to start the test system.
114 * @param label name for command.
115 * @param .
116 * @param local_m Number of nodes in a network namespace. //TODO make this a unsigned int
117 * @param global_n Number of network namespaces. //TODO make this a unsigned int
118 * @return command.
119 */
120struct GNUNET_TESTING_Command
121GNUNET_TESTING_cmd_stop_testing_system (const char *label,
122 const char *helper_start_label,
123 char *local_m,
124 char *global_n
125 )
126{
127 struct StopHelperState *shs;
128
129 shs = GNUNET_new (struct StopHelperState);
130 shs->helper_start_label = helper_start_label;
131 shs->local_m = local_m;
132 shs->global_n = global_n;
133
134 struct GNUNET_TESTING_Command cmd = {
135 .cls = shs,
136 .label = label,
137 .run = &stop_testing_system_run,
138 .cleanup = &stop_testing_system_cleanup,
139 .traits = &stop_testing_system_traits
140 };
141
142 return cmd;
143}
diff --git a/src/testing/testing_api_cmd_send_peer_ready.c b/src/testing/testing_api_cmd_send_peer_ready.c
index 27761c4d5..016837214 100644
--- a/src/testing/testing_api_cmd_send_peer_ready.c
+++ b/src/testing/testing_api_cmd_send_peer_ready.c
@@ -26,18 +26,33 @@
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
32/**
33 * Struct to hold information for callbacks.
34 *
35 */
33struct SendPeerReadyState 36struct SendPeerReadyState
34{ 37{
35 TESTBED_CMD_HELPER_write_cb write_message; 38 /**
36 39 * Callback to write messages to the master loop.
40 *
41 */
42 TESTING_CMD_HELPER_write_cb write_message;
43
44 /**
45 * The message send back to the master loop.
46 *
47 */
37 struct GNUNET_CMDS_PEER_STARTED *reply; 48 struct GNUNET_CMDS_PEER_STARTED *reply;
38}; 49};
39 50
40 51
52/**
53 * Trait function of this cmd does nothing.
54 *
55 */
41static int 56static int
42send_peer_ready_traits (void *cls, 57send_peer_ready_traits (void *cls,
43 const void **ret, 58 const void **ret,
@@ -48,6 +63,10 @@ send_peer_ready_traits (void *cls,
48} 63}
49 64
50 65
66/**
67 * The cleanup function of this cmd frees resources the cmd allocated.
68 *
69 */
51static void 70static void
52send_peer_ready_cleanup (void *cls, 71send_peer_ready_cleanup (void *cls,
53 const struct GNUNET_TESTING_Command *cmd) 72 const struct GNUNET_TESTING_Command *cmd)
@@ -59,6 +78,10 @@ send_peer_ready_cleanup (void *cls,
59} 78}
60 79
61 80
81/**
82 * This function sends a GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED message to the master loop.
83 *
84 */
62static void 85static void
63send_peer_ready_run (void *cls, 86send_peer_ready_run (void *cls,
64 const struct GNUNET_TESTING_Command *cmd, 87 const struct GNUNET_TESTING_Command *cmd,
@@ -68,7 +91,7 @@ send_peer_ready_run (void *cls,
68 struct GNUNET_CMDS_PEER_STARTED *reply; 91 struct GNUNET_CMDS_PEER_STARTED *reply;
69 size_t msg_length; 92 size_t msg_length;
70 93
71 msg_length = sizeof(struct GNUNET_CMDS_HelperInit);// GNUNET_CMDS_PEER_STARTED); 94 msg_length = sizeof(struct GNUNET_CMDS_PEER_STARTED);
72 reply = GNUNET_new (struct GNUNET_CMDS_PEER_STARTED); 95 reply = GNUNET_new (struct GNUNET_CMDS_PEER_STARTED);
73 reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED); 96 reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED);
74 reply->header.size = htons ((uint16_t) msg_length); 97 reply->header.size = htons ((uint16_t) msg_length);
@@ -81,11 +104,12 @@ send_peer_ready_run (void *cls,
81 * Create command. 104 * Create command.
82 * 105 *
83 * @param label name for command. 106 * @param label name for command.
107 * @param write_message Callback to write messages to the master loop.
84 * @return command. 108 * @return command.
85 */ 109 */
86struct GNUNET_TESTING_Command 110struct GNUNET_TESTING_Command
87GNUNET_TESTING_cmd_send_peer_ready (const char *label, 111GNUNET_TESTING_cmd_send_peer_ready (const char *label,
88 TESTBED_CMD_HELPER_write_cb write_message) 112 TESTING_CMD_HELPER_write_cb write_message)
89{ 113{
90 struct SendPeerReadyState *sprs; 114 struct SendPeerReadyState *sprs;
91 115
diff --git a/src/testing/testing_api_cmd_system_create.c b/src/testing/testing_api_cmd_system_create.c
index 2007b4ef3..f3a0b1a4c 100644
--- a/src/testing/testing_api_cmd_system_create.c
+++ b/src/testing/testing_api_cmd_system_create.c
@@ -28,6 +28,10 @@
28#include "gnunet_testing_ng_lib.h" 28#include "gnunet_testing_ng_lib.h"
29#include "gnunet_testing_lib.h" 29#include "gnunet_testing_lib.h"
30 30
31/**
32 * Struct to hold information for callbacks.
33 *
34 */
31struct TestSystemState 35struct TestSystemState
32{ 36{
33 struct GNUNET_TESTING_System *test_system; 37 struct GNUNET_TESTING_System *test_system;
@@ -36,6 +40,10 @@ struct TestSystemState
36}; 40};
37 41
38 42
43/**
44 * The run method of this cmd will setup a test environment for a node.
45 *
46 */
39static void 47static void
40system_create_run (void *cls, 48system_create_run (void *cls,
41 const struct GNUNET_TESTING_Command *cmd, 49 const struct GNUNET_TESTING_Command *cmd,
@@ -54,6 +62,11 @@ system_create_run (void *cls,
54 "system created\n"); 62 "system created\n");
55} 63}
56 64
65
66/**
67 * This function prepares an array with traits.
68 *
69 */
57static int 70static int
58system_create_traits (void *cls, 71system_create_traits (void *cls,
59 const void **ret, 72 const void **ret,
@@ -79,6 +92,12 @@ system_create_traits (void *cls,
79} 92}
80 93
81 94
95/**
96 * Function to get the trait with struct GNUNET_TESTING_System
97 *
98 * @param[out] test_system The struct GNUNET_TESTING_System.
99 * @return #GNUNET_OK if no error occurred, #GNUNET_SYSERR otherwise.
100 */
82int 101int
83GNUNET_TESTING_get_trait_test_system (const struct 102GNUNET_TESTING_get_trait_test_system (const struct
84 GNUNET_TESTING_Command *cmd, 103 GNUNET_TESTING_Command *cmd,
@@ -91,13 +110,16 @@ GNUNET_TESTING_get_trait_test_system (const struct
91} 110}
92 111
93 112
113/**
114 * The cleanup function of this cmd frees resources the cmd allocated.
115 *
116 */
94static void 117static void
95system_create_cleanup (void *cls, 118system_create_cleanup (void *cls,
96 const struct GNUNET_TESTING_Command *cmd) 119 const struct GNUNET_TESTING_Command *cmd)
97{ 120{
98 struct TestSystemState *tss = cls; 121 struct TestSystemState *tss = cls;
99 122
100 GNUNET_free (tss->test_system);
101 GNUNET_free (tss); 123 GNUNET_free (tss);
102} 124}
103 125
@@ -106,6 +128,7 @@ system_create_cleanup (void *cls,
106 * Create command. 128 * Create command.
107 * 129 *
108 * @param label name for command. 130 * @param label name for command.
131 * @param label name for the test environment directory.
109 * @return command. 132 * @return command.
110 */ 133 */
111struct GNUNET_TESTING_Command 134struct GNUNET_TESTING_Command
diff --git a/src/testing/testing_api_cmd_system_destroy.c b/src/testing/testing_api_cmd_system_destroy.c
new file mode 100644
index 000000000..5ed0c2fd2
--- /dev/null
+++ b/src/testing/testing_api_cmd_system_destroy.c
@@ -0,0 +1,116 @@
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_system_destroy.c
23 * @brief cmd to destroy a testing system handle.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_testing_ng_lib.h"
29#include "gnunet_testing_lib.h"
30
31
32/**
33 * Struct to hold information for callbacks.
34 *
35 */
36struct TestSystemState
37{
38 // Label of the cmd which started the test system.
39 const char *create_label;
40};
41
42
43/**
44 * The run method of this cmd will remove the test environment for a node.
45 *
46 */
47static void
48system_destroy_run (void *cls,
49 const struct GNUNET_TESTING_Command *cmd,
50 struct GNUNET_TESTING_Interpreter *is)
51{
52 struct TestSystemState *tss = cls;
53 const struct GNUNET_TESTING_Command *system_cmd;
54 struct GNUNET_TESTING_System *tl_system;
55
56 system_cmd = GNUNET_TESTING_interpreter_lookup_command (tss->create_label);
57 GNUNET_TESTING_get_trait_test_system (system_cmd,
58 &tl_system);
59 GNUNET_TESTING_system_destroy (tl_system, GNUNET_YES);
60}
61
62
63/**
64 * The cleanup function of this cmd frees resources the cmd allocated.
65 *
66 */
67static void
68system_destroy_cleanup (void *cls,
69 const struct GNUNET_TESTING_Command *cmd)
70{
71 struct TestSystemState *tss = cls;
72
73 GNUNET_free (tss);
74}
75
76
77/**
78 * Trait function of this cmd does nothing.
79 *
80 */
81static int
82system_destroy_traits (void *cls,
83 const void **ret,
84 const char *trait,
85 unsigned int index)
86{
87 return GNUNET_OK;
88}
89
90
91/**
92 * Create command.
93 *
94 * @param label name for command.
95 * @param create_label Label of the cmd which started the test system.
96 * @return command.
97 */
98struct GNUNET_TESTING_Command
99GNUNET_TESTING_cmd_system_destroy (const char *label,
100 const char *create_label)
101{
102 struct TestSystemState *tss;
103
104 tss = GNUNET_new (struct TestSystemState);
105 tss->create_label = create_label;
106
107 struct GNUNET_TESTING_Command cmd = {
108 .cls = tss,
109 .label = label,
110 .run = &system_destroy_run,
111 .cleanup = &system_destroy_cleanup,
112 .traits = &system_destroy_traits
113 };
114
115 return cmd;
116}
diff --git a/src/testing/testing_api_loop.c b/src/testing/testing_api_loop.c
index f4fa4e17e..0c24c0e26 100644
--- a/src/testing/testing_api_loop.c
+++ b/src/testing/testing_api_loop.c
@@ -35,6 +35,7 @@
35 35
36struct GNUNET_TESTING_Interpreter *is; 36struct GNUNET_TESTING_Interpreter *is;
37 37
38
38/** 39/**
39 * Closure used to sync an asynchronous with an synchronous command. 40 * Closure used to sync an asynchronous with an synchronous command.
40 */ 41 */
@@ -57,6 +58,7 @@ struct SyncTaskClosure
57 struct GNUNET_TESTING_Interpreter *is; 58 struct GNUNET_TESTING_Interpreter *is;
58}; 59};
59 60
61
60/** 62/**
61* Closure used to run the finish task. 63* Closure used to run the finish task.
62*/ 64*/
@@ -74,6 +76,7 @@ struct FinishTaskClosure
74 struct GNUNET_TESTING_Interpreter *is; 76 struct GNUNET_TESTING_Interpreter *is;
75}; 77};
76 78
79
77/** 80/**
78 * Lookup command by label. 81 * Lookup command by label.
79 * 82 *
@@ -185,6 +188,10 @@ interpreter_next (void *cls)
185} 188}
186 189
187 190
191/**
192 * This function checks if the finish function of a command returns GNUNET_YES, when the command is finished. In this case the finish function might have called interpreter_next. IF GNUNET_NO was returned this function is added to the scheduler again. In case of an error interpreter_fail is called.
193 *
194 */
188static void 195static void
189run_finish_task_next (void *cls) 196run_finish_task_next (void *cls)
190{ 197{
@@ -212,6 +219,12 @@ run_finish_task_next (void *cls)
212} 219}
213 220
214 221
222/**
223 * This function checks if the finish function of an asynchronous command returns GNUNET_YES, when the command is finished. In this case the finish function might have called interpreter_next. IF GNUNET_NO was returned this function is added to the scheduler again. In case of an error interpreter_fail is called.
224 *
225 * //TODO run_finish_task_next and this function can be merged.
226 *
227 */
215static void 228static void
216run_finish_task_sync (void *cls) 229run_finish_task_sync (void *cls)
217{ 230{
@@ -248,13 +261,17 @@ run_finish_task_sync (void *cls)
248 } 261 }
249 else 262 else
250 { 263 {
251 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 264 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
252 "Sync task finished with an error.\n"); 265 "Sync task finished with an error.\n");
253 GNUNET_TESTING_interpreter_fail (); 266 GNUNET_TESTING_interpreter_fail ();
254 } 267 }
255} 268}
256 269
257 270
271/**
272 * run method of the command created by the interpreter to wait for another command to finish.
273 *
274 */
258static void 275static void
259start_finish_on_ref (void *cls, 276start_finish_on_ref (void *cls,
260 const struct GNUNET_TESTING_Command *cmd, 277 const struct GNUNET_TESTING_Command *cmd,
@@ -277,6 +294,17 @@ start_finish_on_ref (void *cls,
277} 294}
278 295
279 296
297/**
298 * Create (synchronous) command that waits for another command to finish.
299 * If @a cmd_ref did not finish after @a timeout, this command will fail
300 * the test case.
301 *
302 * @param finish_label label for this command
303 * @param cmd_ref reference to a previous command which we should
304 * wait for (call `finish()` on)
305 * @param timeout how long to wait at most for @a cmd_ref to finish
306 * @return a finish-command.
307 */
280const struct GNUNET_TESTING_Command 308const struct GNUNET_TESTING_Command
281GNUNET_TESTING_cmd_finish (const char *finish_label, 309GNUNET_TESTING_cmd_finish (const char *finish_label,
282 const char *cmd_ref, 310 const char *cmd_ref,
@@ -340,7 +368,7 @@ GNUNET_TESTING_interpreter_fail ()
340 while (GNUNET_TESTING_cmd_is_batch (cmd)) 368 while (GNUNET_TESTING_cmd_is_batch (cmd))
341 { 369 {
342 cmd = GNUNET_TESTING_cmd_batch_get_current (cmd); 370 cmd = GNUNET_TESTING_cmd_batch_get_current (cmd);
343 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 371 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
344 "Batch is at command `%s'\n", 372 "Batch is at command `%s'\n",
345 cmd->label); 373 cmd->label);
346 } 374 }
@@ -354,7 +382,7 @@ GNUNET_TESTING_interpreter_fail ()
354 382
355 if (NULL == cmd->label) 383 if (NULL == cmd->label)
356 { 384 {
357 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 385 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
358 "Failed at command `%s'\n", 386 "Failed at command `%s'\n",
359 cmd->label); 387 cmd->label);
360 388
@@ -415,7 +443,7 @@ interpreter_run (void *cls)
415 if (NULL == cmd->label) 443 if (NULL == cmd->label)
416 { 444 {
417 445
418 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 446 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
419 "Running command END %p\n", 447 "Running command END %p\n",
420 is); 448 is);
421 is->result = GNUNET_OK; 449 is->result = GNUNET_OK;
@@ -424,7 +452,7 @@ interpreter_run (void *cls)
424 } 452 }
425 else if (NULL != cmd) 453 else if (NULL != cmd)
426 { 454 {
427 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 455 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
428 "Running command `%s' %p\n", 456 "Running command `%s' %p\n",
429 cmd->label, 457 cmd->label,
430 is); 458 is);
@@ -478,8 +506,14 @@ do_shutdown (void *cls)
478 for (unsigned int j = 0; 506 for (unsigned int j = 0;
479 NULL != (cmd = &is->commands[j])->label; 507 NULL != (cmd = &is->commands[j])->label;
480 j++) { 508 j++) {
509 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
510 "Cleaning up cmd %s\n",
511 cmd->label);
481 cmd->cleanup (cmd->cls, 512 cmd->cleanup (cmd->cls,
482 cmd); 513 cmd);
514 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
515 "Cleaned up cmd %s\n",
516 cmd->label);
483 } 517 }
484 518
485 if (NULL != is->finish_task) 519 if (NULL != is->finish_task)
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 */