aboutsummaryrefslogtreecommitdiff
path: root/src/testing
diff options
context:
space:
mode:
Diffstat (limited to 'src/testing')
-rw-r--r--src/testing/.gitignore7
-rw-r--r--src/testing/Makefile.am169
-rw-r--r--src/testing/gnunet-cmds-helper.c589
-rw-r--r--src/testing/gnunet-testing.c444
-rw-r--r--src/testing/list-keys.c112
-rwxr-xr-xsrc/testing/netjail_core.sh116
-rwxr-xr-xsrc/testing/netjail_core_v2.sh260
-rwxr-xr-xsrc/testing/netjail_exec.sh16
-rwxr-xr-xsrc/testing/netjail_exec_v2.sh14
-rwxr-xr-xsrc/testing/netjail_start.sh52
-rwxr-xr-xsrc/testing/netjail_start_v2.sh74
-rwxr-xr-xsrc/testing/netjail_stop.sh26
-rwxr-xr-xsrc/testing/netjail_stop_v2.sh59
-rw-r--r--src/testing/test_testing_api_cmd_netjail.c87
-rw-r--r--src/testing/test_testing_defaults.conf25
-rw-r--r--src/testing/test_testing_hello_world.c68
-rw-r--r--src/testing/test_testing_peerstartup.c143
-rw-r--r--src/testing/test_testing_peerstartup2.c222
-rw-r--r--src/testing/test_testing_plugin_testcmd.c116
-rw-r--r--src/testing/test_testing_portreservation.c105
-rw-r--r--src/testing/test_testing_servicestartup.c75
-rw-r--r--src/testing/test_testing_sharedservices.c167
-rw-r--r--src/testing/test_testing_sharedservices.conf30
-rw-r--r--src/testing/testing.c2284
-rw-r--r--src/testing/testing.conf11
-rw-r--r--src/testing/testing.h74
-rw-r--r--src/testing/testing_api_cmd_batch.c256
-rw-r--r--src/testing/testing_api_cmd_block_until_all_peers_started.c139
-rw-r--r--src/testing/testing_api_cmd_block_until_external_trigger.c139
-rw-r--r--src/testing/testing_api_cmd_hello_world.c121
-rw-r--r--src/testing/testing_api_cmd_hello_world_birth.c159
-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.c610
-rw-r--r--src/testing/testing_api_cmd_netjail_start_testsystem_v2.c720
-rw-r--r--src/testing/testing_api_cmd_netjail_start_v2.c249
-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_netjail_stop_testsystem_v2.c143
-rw-r--r--src/testing/testing_api_cmd_netjail_stop_v2.c225
-rw-r--r--src/testing/testing_api_cmd_send_peer_ready.c128
-rw-r--r--src/testing/testing_api_cmd_system_create.c152
-rw-r--r--src/testing/testing_api_cmd_system_destroy.c116
-rw-r--r--src/testing/testing_api_loop.c599
-rw-r--r--src/testing/testing_api_trait_cmd.c79
-rw-r--r--src/testing/testing_api_trait_process.c81
-rw-r--r--src/testing/testing_api_traits.c81
-rw-r--r--src/testing/testing_cmds.h90
-rwxr-xr-xsrc/testing/topo.sh95
49 files changed, 0 insertions, 10275 deletions
diff --git a/src/testing/.gitignore b/src/testing/.gitignore
deleted file mode 100644
index f350da1f2..000000000
--- a/src/testing/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
1list-keys
2gnunet-testing
3test_testing_peerstartup
4test_testing_peerstartup2
5test_testing_portreservation
6test_testing_servicestartup
7test_testing_sharedservices
diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am
deleted file mode 100644
index efb22b279..000000000
--- a/src/testing/Makefile.am
+++ /dev/null
@@ -1,169 +0,0 @@
1# This Makefile.am is in the public domain
2AM_CPPFLAGS = -I$(top_srcdir)/src/include
3
4if USE_COVERAGE
5 AM_CFLAGS = --coverage -O0
6 XLIB = -lgcov
7endif
8
9libexecdir= $(pkglibdir)/libexec/
10
11pkgcfgdir= $(pkgdatadir)/config.d/
12
13dist_pkgcfg_DATA = \
14 testing.conf
15
16libexec_PROGRAMS = \
17 gnunet-cmds-helper
18
19plugindir = $(libdir)/gnunet
20
21plugin_LTLIBRARIES = \
22 libgnunet_test_testing_plugin_testcmd.la
23
24lib_LTLIBRARIES = \
25 libgnunettesting.la
26
27gnunet_cmds_helper_SOURCES = \
28 gnunet-cmds-helper.c
29gnunet_cmds_helper_LDADD = $(XLIB) \
30 $(top_builddir)/src/util/libgnunetutil.la \
31 libgnunettesting.la \
32 $(LTLIBINTL) $(Z_LIBS)
33
34libgnunet_test_testing_plugin_testcmd_la_SOURCES = \
35 test_testing_plugin_testcmd.c
36libgnunet_test_testing_plugin_testcmd_la_LIBADD = \
37 $(top_builddir)/src/util/libgnunetutil.la \
38 $(top_builddir)/src/arm/libgnunetarm.la \
39 libgnunettesting.la \
40 $(top_builddir)/src/statistics/libgnunetstatistics.la \
41 $(LTLIBINTL)
42libgnunet_test_testing_plugin_testcmd_la_LDFLAGS = \
43 $(GN_PLUGIN_LDFLAGS)
44
45libgnunettesting_la_SOURCES = \
46 testing_api_cmd_local_test_finished.c \
47 testing_api_cmd_send_peer_ready.c \
48 testing_api_cmd_block_until_all_peers_started.c \
49 testing_api_cmd_block_until_external_trigger.c \
50 testing_api_cmd_netjail_start.c \
51 testing_api_cmd_netjail_start_v2.c \
52 testing_api_cmd_netjail_start_testsystem.c \
53 testing_api_cmd_netjail_start_testsystem_v2.c \
54 testing_api_cmd_netjail_stop_testsystem.c \
55 testing_api_cmd_netjail_stop_testsystem_v2.c \
56 testing_api_cmd_netjail_stop.c \
57 testing_api_cmd_netjail_stop_v2.c \
58 testing.c testing.h \
59 testing_api_cmd_system_create.c \
60 testing_api_cmd_system_destroy.c \
61 testing_api_cmd_batch.c \
62 testing_api_cmd_hello_world.c \
63 testing_api_cmd_hello_world_birth.c \
64 testing_api_loop.c \
65 testing_api_trait_cmd.c \
66 testing_api_trait_process.c \
67 testing_api_traits.c
68libgnunettesting_la_LIBADD = \
69 $(top_builddir)/src/arm/libgnunetarm.la \
70 $(top_builddir)/src/util/libgnunetutil.la \
71 $(LTLIBINTL)
72libgnunettesting_la_LDFLAGS = \
73 $(GN_LIB_LDFLAGS) \
74 -version-info 2:0:1
75
76bin_PROGRAMS = \
77 gnunet-testing
78
79noinst_PROGRAMS = \
80 list-keys
81
82gnunet_testing_SOURCES = \
83 gnunet-testing.c
84gnunet_testing_LDADD = \
85 libgnunettesting.la \
86 $(top_builddir)/src/util/libgnunetutil.la \
87 $(GN_LIBINTL)
88
89list_keys_SOURCES = \
90 list-keys.c
91list_keys_LDADD = \
92 $(top_builddir)/src/util/libgnunetutil.la \
93 $(GN_LIBINTL)
94
95
96check_PROGRAMS = \
97 test_testing_topology \
98 test_testing_api_cmd_netjail \
99 test_testing_hello_world \
100 test_testing_portreservation \
101 test_testing_servicestartup \
102 test_testing_peerstartup \
103 test_testing_peerstartup2 \
104 test_testing_sharedservices
105
106if ENABLE_TEST_RUN
107AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME;
108TESTS = \
109 test_testing_topology \
110 test_testing_api_cmd_netjail \
111 test_testing_hello_world \
112 test_testing_portreservation \
113 test_testing_peerstartup \
114 test_testing_peerstartup2 \
115 test_testing_servicestartup
116endif
117
118test_testing_topology_SOURCES = \
119 test_testing_topology.c
120test_testing_topology_LDADD = \
121 libgnunettesting.la \
122 $(top_builddir)/src/util/libgnunetutil.la
123
124test_testing_api_cmd_netjail_SOURCES = \
125 test_testing_api_cmd_netjail.c
126test_testing_api_cmd_netjail_LDADD = \
127 libgnunettesting.la \
128 $(top_builddir)/src/util/libgnunetutil.la
129
130test_testing_hello_world_SOURCES = \
131 test_testing_hello_world.c
132test_testing_hello_world_LDADD = \
133 libgnunettesting.la \
134 $(top_builddir)/src/util/libgnunetutil.la
135
136test_testing_portreservation_SOURCES = \
137 test_testing_portreservation.c
138test_testing_portreservation_LDADD = \
139 libgnunettesting.la \
140 $(top_builddir)/src/util/libgnunetutil.la
141
142test_testing_peerstartup_SOURCES = \
143 test_testing_peerstartup.c
144test_testing_peerstartup_LDADD = \
145 libgnunettesting.la \
146 $(top_builddir)/src/util/libgnunetutil.la
147
148test_testing_peerstartup2_SOURCES = \
149 test_testing_peerstartup2.c
150test_testing_peerstartup2_LDADD = \
151 libgnunettesting.la \
152 $(top_builddir)/src/util/libgnunetutil.la
153
154test_testing_servicestartup_SOURCES = \
155 test_testing_servicestartup.c
156test_testing_servicestartup_LDADD = \
157 libgnunettesting.la \
158 $(top_builddir)/src/util/libgnunetutil.la
159
160test_testing_sharedservices_SOURCES = \
161 test_testing_sharedservices.c
162test_testing_sharedservices_LDADD = \
163 libgnunettesting.la \
164 $(top_builddir)/src/util/libgnunetutil.la
165
166EXTRA_DIST = \
167 test_testing_defaults.conf \
168 test_testing_sharedservices.conf \
169 testing_cmds.h
diff --git a/src/testing/gnunet-cmds-helper.c b/src/testing/gnunet-cmds-helper.c
deleted file mode 100644
index e50db0cf6..000000000
--- a/src/testing/gnunet-cmds-helper.c
+++ /dev/null
@@ -1,589 +0,0 @@
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 KNOWN_BASE_IP "92.68.151."
61
62#define ROUTER_BASE_IP "92.68.150."
63
64/**
65 * Handle for a plugin.
66 */
67struct Plugin
68{
69 /**
70 * Name of the shared library.
71 */
72 char *library_name;
73
74 /**
75 * Plugin API.
76 */
77 struct GNUNET_TESTING_PluginFunctions *api;
78
79 /**
80 * IP address of the specific node the helper is running for.
81 *
82 */
83 char *node_ip;
84
85 /**
86 * Name of the test case plugin.
87 *
88 */
89 char *plugin_name;
90
91 /**
92 * The number of namespaces
93 *
94 */
95 char *global_n;
96
97 /**
98 * The number of local nodes per namespace.
99 *
100 */
101 char *local_m;
102
103 /**
104 * The number of the namespace this node is in.
105 *
106 */
107 char *n;
108
109 /**
110 * The number of the node in the namespace.
111 *
112 */
113 char *m;
114};
115
116/**
117 * Struct with information about a specific node and the whole network namespace setup.
118 *
119 */
120struct NodeIdentifier
121{
122 /**
123 * The number of the namespace this node is in.
124 *
125 */
126 char *n;
127
128 /**
129 * The number of the node in the namespace.
130 *
131 */
132 char *m;
133
134 /**
135 * The number of namespaces
136 *
137 */
138 char *global_n;
139
140 /**
141 * The number of local nodes per namespace.
142 *
143 */
144 char *local_m;
145};
146
147/**
148 * Context for a single write on a chunk of memory
149 */
150struct WriteContext
151{
152 /**
153 * The data to write
154 */
155 void *data;
156
157 /**
158 * The length of the data
159 */
160 size_t length;
161
162 /**
163 * The current position from where the write operation should begin
164 */
165 size_t pos;
166};
167
168/**
169 * The process handle to the testbed service
170
171static struct GNUNET_OS_Process *cmd_binary_process;*/
172
173/**
174 * Plugin to dynamically load a test case.
175 */
176struct Plugin *plugin;
177
178/**
179 * Handle to the testing system
180 */
181static struct GNUNET_TESTING_System *test_system;
182
183/**
184 * Our message stream tokenizer
185 */
186struct GNUNET_MessageStreamTokenizer *tokenizer;
187
188/**
189 * Disk handle from stdin
190 */
191static struct GNUNET_DISK_FileHandle *stdin_fd;
192
193/**
194 * Disk handle for stdout
195 */
196static struct GNUNET_DISK_FileHandle *stdout_fd;
197
198/**
199 * Pipe used to communicate shutdown via signal.
200 */
201static struct GNUNET_DISK_PipeHandle *sigpipe;
202
203/**
204 * Task identifier for the read task
205 */
206static struct GNUNET_SCHEDULER_Task *read_task_id;
207
208/**
209 * Task identifier for the write task
210 */
211static struct GNUNET_SCHEDULER_Task *write_task_id;
212
213/**
214 * Are we done reading messages from stdin?
215 */
216static int done_reading;
217
218/**
219 * Result to return in case we fail
220 */
221static int status;
222
223
224/**
225 * Task to shut down cleanly
226 *
227 * @param cls NULL
228 */
229static void
230shutdown_task (void *cls)
231{
232
233 LOG_DEBUG ("Shutting down.\n");
234
235 if (NULL != read_task_id)
236 {
237 GNUNET_SCHEDULER_cancel (read_task_id);
238 read_task_id = NULL;
239 }
240 if (NULL != write_task_id)
241 {
242 struct WriteContext *wc;
243
244 wc = GNUNET_SCHEDULER_cancel (write_task_id);
245 write_task_id = NULL;
246 GNUNET_free (wc->data);
247 GNUNET_free (wc);
248 }
249 if (NULL != stdin_fd)
250 (void) GNUNET_DISK_file_close (stdin_fd);
251 if (NULL != stdout_fd)
252 (void) GNUNET_DISK_file_close (stdout_fd);
253 GNUNET_MST_destroy (tokenizer);
254 tokenizer = NULL;
255
256 if (NULL != test_system)
257 {
258 GNUNET_TESTING_system_destroy (test_system, GNUNET_YES);
259 test_system = NULL;
260 }
261}
262
263
264/**
265 * Task to write to the standard out
266 *
267 * @param cls the WriteContext
268 */
269static void
270write_task (void *cls)
271{
272 struct WriteContext *wc = cls;
273 ssize_t bytes_wrote;
274
275 GNUNET_assert (NULL != wc);
276 write_task_id = NULL;
277 bytes_wrote = GNUNET_DISK_file_write (stdout_fd,
278 wc->data + wc->pos,
279 wc->length - wc->pos);
280 if (GNUNET_SYSERR == bytes_wrote)
281 {
282 LOG (GNUNET_ERROR_TYPE_WARNING,
283 "Cannot reply back successful initialization\n");
284 GNUNET_free (wc->data);
285 GNUNET_free (wc);
286 return;
287 }
288 wc->pos += bytes_wrote;
289 if (wc->pos == wc->length)
290 {
291 GNUNET_free (wc->data);
292 GNUNET_free (wc);
293 return;
294 }
295 write_task_id = GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
296 stdout_fd,
297 &write_task,
298 wc);
299}
300
301
302/**
303 * Callback to write a message to the master loop.
304 *
305 */
306static void
307write_message (struct GNUNET_MessageHeader *message, size_t msg_length)
308{
309 struct WriteContext *wc;
310
311 wc = GNUNET_new (struct WriteContext);
312 wc->length = msg_length;
313 wc->data = message;
314 write_task_id = GNUNET_SCHEDULER_add_write_file (
315 GNUNET_TIME_UNIT_FOREVER_REL,
316 stdout_fd,
317 &write_task,
318 wc);
319}
320
321
322/**
323 * Functions with this signature are called whenever a
324 * complete message is received by the tokenizer.
325 *
326 * Do not call #GNUNET_mst_destroy() in this callback
327 *
328 * @param cls identification of the client
329 * @param message the actual message
330 * @return #GNUNET_OK on success,
331 * #GNUNET_NO to stop further processing (no error)
332 * #GNUNET_SYSERR to stop further processing with error
333 */
334static int
335tokenizer_cb (void *cls, const struct GNUNET_MessageHeader *message)
336{
337
338 struct NodeIdentifier *ni = cls;
339 const struct GNUNET_CMDS_HelperInit *msg;
340 struct GNUNET_CMDS_HelperReply *reply;
341 char *binary;
342 char *plugin_name;
343 size_t plugin_name_size;
344 uint16_t msize;
345 size_t msg_length;
346 char *router_ip;
347 char *node_ip;
348 unsigned int namespace_n;
349
350 msize = ntohs (message->size);
351 if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT == ntohs (message->type))
352 {
353 msg = (const struct GNUNET_CMDS_HelperInit *) message;
354 plugin_name_size = ntohs (msg->plugin_name_size);
355 if ((sizeof(struct GNUNET_CMDS_HelperInit) + plugin_name_size) > msize)
356 {
357 GNUNET_break (0);
358 LOG (GNUNET_ERROR_TYPE_WARNING,
359 "Received unexpected message -- exiting\n");
360 goto error;
361 }
362 plugin_name = GNUNET_malloc (plugin_name_size + 1);
363 GNUNET_strlcpy (plugin_name,
364 ((char *) &msg[1]),
365 plugin_name_size + 1);
366
367 binary = GNUNET_OS_get_libexec_binary_path ("gnunet-cmd");
368
369 plugin = GNUNET_new (struct Plugin);
370 plugin->api = GNUNET_PLUGIN_load (plugin_name,
371 NULL);
372 plugin->library_name = GNUNET_strdup (basename (plugin_name));
373
374 plugin->global_n = ni->global_n;
375 plugin->local_m = ni->local_m;
376 plugin->n = ni->n;
377 plugin->m = ni->m;
378
379 router_ip = GNUNET_malloc (strlen (ROUTER_BASE_IP) + strlen (plugin->n)
380 + 1);
381 strcpy (router_ip, ROUTER_BASE_IP);
382 strcat (router_ip, plugin->n);
383
384 sscanf (plugin->n, "%u", &namespace_n);
385
386 if (0 == namespace_n)
387 {
388 LOG (GNUNET_ERROR_TYPE_ERROR,
389 "known node n: %s\n",
390 plugin->n);
391 node_ip = GNUNET_malloc (strlen (KNOWN_BASE_IP) + strlen (plugin->m) + 1);
392 strcat (node_ip, KNOWN_BASE_IP);
393 }
394 else
395 {
396 LOG (GNUNET_ERROR_TYPE_ERROR,
397 "subnet node n: %s\n",
398 plugin->n);
399 node_ip = GNUNET_malloc (strlen (NODE_BASE_IP) + strlen (plugin->m) + 1);
400 strcat (node_ip, NODE_BASE_IP);
401 }
402 strcat (node_ip, plugin->m);
403
404 plugin->api->start_testcase (&write_message, router_ip, node_ip, plugin->m,
405 plugin->n, plugin->local_m);
406
407 GNUNET_free (binary);
408
409 msg_length = sizeof(struct GNUNET_CMDS_HelperReply);
410 reply = GNUNET_new (struct GNUNET_CMDS_HelperReply);
411 reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY);
412 reply->header.size = htons ((uint16_t) msg_length);
413
414 write_message ((struct GNUNET_MessageHeader *) reply, msg_length);
415
416 return GNUNET_OK;
417 }
418 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED == ntohs (
419 message->type))
420 {
421 plugin->api->all_peers_started ();
422 return GNUNET_OK;
423 }
424 else
425 {
426 LOG (GNUNET_ERROR_TYPE_WARNING, "Received unexpected message -- exiting\n");
427 goto error;
428 }
429
430
431 error:
432 status = GNUNET_SYSERR;
433 LOG (GNUNET_ERROR_TYPE_ERROR,
434 "tokenizer shutting down!\n");
435 GNUNET_SCHEDULER_shutdown ();
436 return GNUNET_SYSERR;
437}
438
439
440/**
441 * Task to read from stdin
442 *
443 * @param cls NULL
444 */
445static void
446read_task (void *cls)
447{
448 char buf[GNUNET_MAX_MESSAGE_SIZE];
449 ssize_t sread;
450
451 read_task_id = NULL;
452 sread = GNUNET_DISK_file_read (stdin_fd, buf, sizeof(buf));
453 if ((GNUNET_SYSERR == sread) || (0 == sread))
454 {
455 LOG_DEBUG ("STDIN closed\n");
456 GNUNET_SCHEDULER_shutdown ();
457 return;
458 }
459 if (GNUNET_YES == done_reading)
460 {
461 /* didn't expect any more data! */
462 GNUNET_break_op (0);
463 LOG (GNUNET_ERROR_TYPE_ERROR,
464 "tokenizer shutting down during reading, didn't expect any more data!\n");
465 GNUNET_SCHEDULER_shutdown ();
466 return;
467 }
468 LOG_DEBUG ("Read %u bytes\n", (unsigned int) sread);
469 /* FIXME: could introduce a GNUNET_MST_read2 to read
470 directly from 'stdin_fd' and save a memcpy() here */
471 if (GNUNET_OK !=
472 GNUNET_MST_from_buffer (tokenizer, buf, sread, GNUNET_NO, GNUNET_NO))
473 {
474 GNUNET_break (0);
475 LOG (GNUNET_ERROR_TYPE_ERROR,
476 "tokenizer shutting down during reading, writing to buffer failed!\n");
477 GNUNET_SCHEDULER_shutdown ();
478 return;
479 }
480 read_task_id /* No timeout while reading */
481 = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
482 stdin_fd,
483 &read_task,
484 NULL);
485}
486
487
488/**
489 * Main function that will be run.
490 *
491 * @param cls closure
492 * @param args remaining command-line arguments
493 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
494 * @param cfg configuration
495 */
496static void
497run (void *cls,
498 char *const *args,
499 const char *cfgfile,
500 const struct GNUNET_CONFIGURATION_Handle *cfg)
501{
502 struct NodeIdentifier *ni = cls;
503
504 LOG_DEBUG ("Starting interpreter loop helper...\n");
505
506 tokenizer = GNUNET_MST_create (&tokenizer_cb, ni);
507 stdin_fd = GNUNET_DISK_get_handle_from_native (stdin);
508 stdout_fd = GNUNET_DISK_get_handle_from_native (stdout);
509 read_task_id = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
510 stdin_fd,
511 &read_task,
512 NULL);
513 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
514}
515
516
517/**
518 * Signal handler called for SIGCHLD.
519 */
520static void
521sighandler_child_death ()
522{
523 static char c;
524 int old_errno; /* back-up errno */
525
526 old_errno = errno;
527 GNUNET_break (
528 1 ==
529 GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle (sigpipe,
530 GNUNET_DISK_PIPE_END_WRITE),
531 &c,
532 sizeof(c)));
533 errno = old_errno;
534}
535
536
537/**
538 * Main function
539 *
540 * @param argc the number of command line arguments
541 * @param argv command line arg array
542 * @return return code
543 */
544int
545main (int argc, char **argv)
546{
547 struct NodeIdentifier *ni;
548 struct GNUNET_SIGNAL_Context *shc_chld;
549 struct GNUNET_GETOPT_CommandLineOption options[] =
550 { GNUNET_GETOPT_OPTION_END };
551 int ret;
552
553 GNUNET_log_setup ("gnunet-cmds-helper",
554 "DEBUG",
555 NULL);
556 ni = GNUNET_new (struct NodeIdentifier);
557 ni->global_n = argv[1];
558 ni->local_m = argv[2];
559 ni->m = argv[3];
560 ni->n = argv[4];
561
562 status = GNUNET_OK;
563 if (NULL ==
564 (sigpipe = GNUNET_DISK_pipe (GNUNET_DISK_PF_NONE)))
565 {
566 GNUNET_break (0);
567 return 1;
568 }
569 shc_chld =
570 GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, &sighandler_child_death);
571 ret = GNUNET_PROGRAM_run (argc,
572 argv,
573 "gnunet-cmds-helper",
574 "Helper for starting a local interpreter loop",
575 options,
576 &run,
577 ni);
578
579 GNUNET_SIGNAL_handler_uninstall (shc_chld);
580 shc_chld = NULL;
581 GNUNET_DISK_pipe_close (sigpipe);
582 GNUNET_free (ni);
583 if (GNUNET_OK != ret)
584 return 1;
585 return (GNUNET_OK == status) ? 0 : 1;
586}
587
588
589/* end of gnunet-cmds-helper.c */
diff --git a/src/testing/gnunet-testing.c b/src/testing/gnunet-testing.c
deleted file mode 100644
index 88906e5fa..000000000
--- a/src/testing/gnunet-testing.c
+++ /dev/null
@@ -1,444 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2001, 2002, 2004, 2005, 2006, 2007, 2009 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/gnunet-testing.c
23 * @brief tool to use testing functionality from cmd line
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_testing_lib.h"
29
30
31#define LOG(kind, ...) GNUNET_log_from (kind, "gnunet-testing", __VA_ARGS__)
32
33
34/**
35 * Final status code.
36 */
37static int ret;
38
39/**
40 * Filename of the hostkey file we should write,
41 * null if we should not write a hostkey file.
42 */
43static char *create_hostkey;
44
45/**
46 * Non-zero if we should create config files.
47 */
48static int create_cfg;
49
50/**
51 * Number of config files to create.
52 */
53static unsigned int create_no;
54
55/**
56 * Filename of the config template to be written.
57 */
58static char *create_cfg_template;
59
60/**
61 * Service we are supposed to run.
62 */
63static char *run_service_name;
64
65/**
66 * File handle to STDIN, for reading restart/quit commands.
67 */
68static struct GNUNET_DISK_FileHandle *fh;
69
70/**
71 * Temporary filename, used with '-r' to write the configuration to.
72 */
73static char *tmpfilename;
74
75/**
76 * Task identifier of the task that waits for stdin.
77 */
78static struct GNUNET_SCHEDULER_Task *tid;
79
80/**
81 * Peer started for '-r'.
82 */
83static struct GNUNET_TESTING_Peer *my_peer;
84
85
86static int
87create_unique_cfgs (const char *template, const unsigned int no)
88{
89 struct GNUNET_TESTING_System *system;
90 int fail;
91 unsigned int cur;
92 char *cur_file;
93 struct GNUNET_CONFIGURATION_Handle *cfg_new;
94 struct GNUNET_CONFIGURATION_Handle *cfg_tmpl;
95
96 if (GNUNET_NO == GNUNET_DISK_file_test (template))
97 {
98 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
99 "Configuration template `%s': file not found\n",
100 create_cfg_template);
101 return 1;
102 }
103 cfg_tmpl = GNUNET_CONFIGURATION_create ();
104
105 /* load template */
106 if ((create_cfg_template != NULL) &&
107 (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg_tmpl, create_cfg_template)))
108 {
109 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
110 "Could not load template `%s'\n",
111 create_cfg_template);
112 GNUNET_CONFIGURATION_destroy (cfg_tmpl);
113
114 return 1;
115 }
116 /* load defaults */
117 if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg_tmpl, NULL))
118 {
119 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
120 "Could not load template `%s'\n",
121 create_cfg_template);
122 GNUNET_CONFIGURATION_destroy (cfg_tmpl);
123 return 1;
124 }
125
126 fail = GNUNET_NO;
127 system =
128 GNUNET_TESTING_system_create ("testing", NULL /* controller */, NULL, NULL);
129 for (cur = 0; cur < no; cur++)
130 {
131 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
132 "Creating configuration no. %u \n",
133 cur);
134 if (create_cfg_template != NULL)
135 GNUNET_asprintf (&cur_file, "%04u-%s", cur, create_cfg_template);
136 else
137 GNUNET_asprintf (&cur_file, "%04u%s", cur, ".conf");
138
139 cfg_new = GNUNET_CONFIGURATION_dup (cfg_tmpl);
140 if (GNUNET_OK != GNUNET_TESTING_configuration_create (system, cfg_new))
141 {
142 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
143 "Could not create another configuration\n");
144 GNUNET_CONFIGURATION_destroy (cfg_new);
145 fail = GNUNET_YES;
146 break;
147 }
148 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
149 "Writing configuration no. %u to file `%s' \n",
150 cur,
151 cur_file);
152 if (GNUNET_OK != GNUNET_CONFIGURATION_write (cfg_new, cur_file))
153 {
154 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
155 "Failed to write configuration no. %u \n",
156 cur);
157 fail = GNUNET_YES;
158 }
159 GNUNET_CONFIGURATION_destroy (cfg_new);
160 GNUNET_free (cur_file);
161 if (GNUNET_YES == fail)
162 break;
163 }
164 GNUNET_CONFIGURATION_destroy (cfg_tmpl);
165 GNUNET_TESTING_system_destroy (system, GNUNET_NO);
166 if (GNUNET_YES == fail)
167 return 1;
168 return 0;
169}
170
171
172static int
173create_hostkeys (const unsigned int no)
174{
175 struct GNUNET_TESTING_System *system;
176 struct GNUNET_PeerIdentity id;
177 struct GNUNET_DISK_FileHandle *fd;
178 struct GNUNET_CRYPTO_EddsaPrivateKey *pk;
179
180 system = GNUNET_TESTING_system_create ("testing", NULL, NULL, NULL);
181 pk = GNUNET_TESTING_hostkey_get (system, create_no, &id);
182 if (NULL == pk)
183 {
184 fprintf (stderr,
185 _ ("Could not extract hostkey %u (offset too large?)\n"),
186 create_no);
187 GNUNET_TESTING_system_destroy (system, GNUNET_YES);
188 return 1;
189 }
190 (void) GNUNET_DISK_directory_create_for_file (create_hostkey);
191 fd =
192 GNUNET_DISK_file_open (create_hostkey,
193 GNUNET_DISK_OPEN_READWRITE | GNUNET_DISK_OPEN_CREATE,
194 GNUNET_DISK_PERM_USER_READ
195 | GNUNET_DISK_PERM_USER_WRITE);
196 GNUNET_assert (fd != NULL);
197 ret = GNUNET_DISK_file_write (fd,
198 pk,
199 sizeof(struct GNUNET_CRYPTO_EddsaPrivateKey));
200 GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd));
201 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
202 "transport-testing",
203 "Wrote hostkey to file: `%s'\n",
204 create_hostkey);
205 GNUNET_free (pk);
206 GNUNET_TESTING_system_destroy (system, GNUNET_YES);
207 return 0;
208}
209
210
211/**
212 * Cleanup called by signal handlers and when stdin is closed.
213 * Removes the temporary file.
214 *
215 * @param cls unused
216 */
217static void
218cleanup (void *cls)
219{
220 if (NULL != tmpfilename)
221 {
222 if (0 != unlink (tmpfilename))
223 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
224 "unlink",
225 tmpfilename);
226 }
227 if (NULL != tid)
228 {
229 GNUNET_SCHEDULER_cancel (tid);
230 tid = NULL;
231 }
232 if (NULL != fh)
233 {
234 GNUNET_DISK_file_close (fh);
235 fh = NULL;
236 }
237}
238
239
240/**
241 * Called whenever we can read stdin non-blocking
242 *
243 * @param cls unused
244 */
245static void
246stdin_cb (void *cls)
247{
248 int c;
249
250 tid = NULL;
251 c = getchar ();
252 switch (c)
253 {
254 case EOF:
255 case 'q':
256 GNUNET_SCHEDULER_shutdown ();
257 return;
258
259 case 'r':
260 if (GNUNET_OK != GNUNET_TESTING_peer_stop (my_peer))
261 LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to stop the peer\n");
262 if (GNUNET_OK != GNUNET_TESTING_peer_start (my_peer))
263 LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to start the peer\n");
264 printf ("restarted\n");
265 fflush (stdout);
266 break;
267
268 case '\n':
269 case '\r':
270 /* ignore whitespace */
271 break;
272
273 default:
274 fprintf (stderr,
275 _ ("Unknown command, use 'q' to quit or 'r' to restart peer\n"));
276 break;
277 }
278 tid = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
279 fh,
280 &stdin_cb,
281 NULL);
282}
283
284
285/**
286 * Main function called by the testing library.
287 * Executed inside a running scheduler.
288 *
289 * @param cls unused
290 * @param cfg configuration of the peer that was started
291 * @param peer handle to the peer
292 */
293static void
294testing_main (void *cls,
295 const struct GNUNET_CONFIGURATION_Handle *cfg,
296 struct GNUNET_TESTING_Peer *peer)
297{
298 my_peer = peer;
299 if (NULL == (tmpfilename = GNUNET_DISK_mktemp ("gnunet-testing")))
300 {
301 GNUNET_break (0);
302 GNUNET_SCHEDULER_shutdown ();
303 return;
304 }
305 if (GNUNET_SYSERR ==
306 GNUNET_CONFIGURATION_write ((struct GNUNET_CONFIGURATION_Handle *) cfg,
307 tmpfilename))
308 {
309 GNUNET_break (0);
310 return;
311 }
312 printf ("ok\n%s\n", tmpfilename);
313 fflush (stdout);
314 GNUNET_SCHEDULER_add_shutdown (&cleanup, NULL);
315 fh = GNUNET_DISK_get_handle_from_native (stdin);
316 tid = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
317 fh,
318 &stdin_cb,
319 NULL);
320}
321
322
323/**
324 * Main function that will be running without scheduler.
325 *
326 * @param cls closure
327 * @param args remaining command-line arguments
328 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
329 * @param cfg configuration
330 */
331static void
332run_no_scheduler (void *cls,
333 char *const *args,
334 const char *cfgfile,
335 const struct GNUNET_CONFIGURATION_Handle *cfg)
336{
337 if (NULL != run_service_name)
338 {
339 ret = GNUNET_TESTING_service_run ("gnunet_service_test",
340 run_service_name,
341 cfgfile,
342 &testing_main,
343 NULL);
344 return;
345 }
346
347 if (GNUNET_YES == create_cfg)
348 {
349 if (create_no > 0)
350 {
351 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
352 "Creating %u configuration files based on template `%s'\n",
353 create_no,
354 create_cfg_template);
355 ret = create_unique_cfgs (create_cfg_template, create_no);
356 }
357 else
358 {
359 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Missing arguments! \n");
360 ret = 1;
361 }
362 }
363 if (NULL != create_hostkey)
364 {
365 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Extracting hostkey %u\n", create_no);
366 ret = create_hostkeys (create_no);
367 }
368 GNUNET_free (create_cfg_template);
369}
370
371
372/**
373 * The main function.
374 *
375 * @param argc number of arguments from the command line
376 * @param argv command line arguments
377 * @return 0 ok, 1 on error
378 */
379int
380main (int argc, char *const *argv)
381{
382 struct GNUNET_GETOPT_CommandLineOption options[] =
383 { GNUNET_GETOPT_option_flag ('C',
384 "cfg",
385 gettext_noop (
386 "create unique configuration files"),
387 &create_cfg),
388 GNUNET_GETOPT_option_string (
389 'k',
390 "key",
391 "FILENAME",
392 gettext_noop ("extract hostkey file from pre-computed hostkey list"),
393 &create_hostkey),
394
395 GNUNET_GETOPT_option_uint (
396 'n',
397 "number",
398 "NUMBER",
399 gettext_noop (
400 "number of unique configuration files to create, or number of the hostkey to extract"),
401 &create_no),
402
403
404 GNUNET_GETOPT_option_string ('t',
405 "template",
406 "FILENAME",
407 gettext_noop ("configuration template"),
408 &create_cfg_template),
409
410 GNUNET_GETOPT_option_string (
411 'r',
412 "run",
413 "SERVICE",
414 gettext_noop (
415 "run the given service, wait on stdin for 'r' (restart) or 'q' (quit)"),
416 &run_service_name),
417 GNUNET_GETOPT_OPTION_END };
418
419 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
420 return 2;
421
422 /* Run without scheduler, because we may want to call
423 * GNUNET_TESTING_service_run, which starts the scheduler on its own.
424 * Furthermore, the other functionality currently does not require the scheduler, too,
425 * but beware when extending gnunet-testing. */
426 ret =
427 (GNUNET_OK ==
428 GNUNET_PROGRAM_run2 (argc,
429 argv,
430 "gnunet-testing",
431 gettext_noop (
432 "Command line tool to access the testing library"),
433 options,
434 &run_no_scheduler,
435 NULL,
436 GNUNET_YES))
437 ? ret
438 : 1;
439 GNUNET_free_nz ((void *) argv);
440 return ret;
441}
442
443
444/* end of gnunet-testing.c */
diff --git a/src/testing/list-keys.c b/src/testing/list-keys.c
deleted file mode 100644
index f65b45a77..000000000
--- a/src/testing/list-keys.c
+++ /dev/null
@@ -1,112 +0,0 @@
1#include "platform.h"
2#include "gnunet_util_lib.h"
3#include "gnunet_testing_lib.h"
4
5static unsigned int nkeys;
6static unsigned int nskip;
7static int result;
8
9/**
10 * Main run function.
11 *
12 * @param cls NULL
13 * @param args arguments passed to GNUNET_PROGRAM_run
14 * @param cfgfile the path to configuration file
15 * @param cfg the configuration file handle
16 */
17static void
18run (void *cls,
19 char *const *args,
20 const char *cfgfile,
21 const struct GNUNET_CONFIGURATION_Handle *config)
22{
23 char *idfile;
24 struct GNUNET_DISK_FileHandle *f;
25 void *data;
26 struct GNUNET_DISK_MapHandle *map;
27 struct GNUNET_CRYPTO_EddsaPrivateKey pkey;
28 struct GNUNET_PeerIdentity id;
29 unsigned int cnt;
30 uint64_t fsize;
31 unsigned int nmax;
32
33 if ((NULL == args) || (NULL == args[0]))
34 {
35 fprintf (stderr, "Need the hostkey file\n");
36 return;
37 }
38 idfile = args[0];
39 if (GNUNET_OK !=
40 GNUNET_DISK_file_size (idfile, &fsize, GNUNET_YES, GNUNET_YES))
41 {
42 GNUNET_break (0);
43 return;
44 }
45 if (0 != (fsize % GNUNET_TESTING_HOSTKEYFILESIZE))
46 {
47 fprintf (stderr, _ ("Incorrect hostkey file format: %s\n"), idfile);
48 return;
49 }
50 f = GNUNET_DISK_file_open (idfile,
51 GNUNET_DISK_OPEN_READ,
52 GNUNET_DISK_PERM_NONE);
53 if (NULL == f)
54 {
55 GNUNET_break (0);
56 return;
57 }
58 data = GNUNET_DISK_file_map (f, &map, GNUNET_DISK_MAP_TYPE_READ, fsize);
59 if (NULL == data)
60 {
61 GNUNET_break (0);
62 GNUNET_DISK_file_close (f);
63 return;
64 }
65 nmax = fsize / GNUNET_TESTING_HOSTKEYFILESIZE;
66 for (cnt = nskip; cnt < (nskip + nkeys); cnt++)
67 {
68 if (nskip + cnt >= nmax)
69 {
70 printf ("Max keys %u reached\n", nmax);
71 break;
72 }
73 GNUNET_memcpy (&pkey,
74 data + (cnt * GNUNET_TESTING_HOSTKEYFILESIZE),
75 GNUNET_TESTING_HOSTKEYFILESIZE);
76 GNUNET_CRYPTO_eddsa_key_get_public (&pkey, &id.public_key);
77 printf ("Key %u: %s\n", cnt, GNUNET_i2s_full (&id));
78 }
79 result = GNUNET_OK;
80 GNUNET_DISK_file_unmap (map);
81 GNUNET_DISK_file_close (f);
82}
83
84
85int
86main (int argc, char *argv[])
87{
88 struct GNUNET_GETOPT_CommandLineOption option[] =
89 { GNUNET_GETOPT_option_uint ('n',
90 "num-keys",
91 "COUNT",
92 gettext_noop ("list COUNT number of keys"),
93 &nkeys),
94 GNUNET_GETOPT_OPTION_END };
95 int ret;
96
97 result = GNUNET_SYSERR;
98 nkeys = 10;
99 ret =
100 GNUNET_PROGRAM_run (argc,
101 argv,
102 "list-keys",
103 "Lists the peer IDs corresponding to the given keys file\n",
104 option,
105 &run,
106 NULL);
107 if (GNUNET_OK != ret)
108 return 1;
109 if (GNUNET_SYSERR == result)
110 return 1;
111 return 0;
112}
diff --git a/src/testing/netjail_core.sh b/src/testing/netjail_core.sh
deleted file mode 100755
index cf350d3fa..000000000
--- a/src/testing/netjail_core.sh
+++ /dev/null
@@ -1,116 +0,0 @@
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_core_v2.sh b/src/testing/netjail_core_v2.sh
deleted file mode 100755
index ef0a54a5e..000000000
--- a/src/testing/netjail_core_v2.sh
+++ /dev/null
@@ -1,260 +0,0 @@
1#!/bin/sh
2#
3
4
5PREFIX=${PPID:?must run from a parent process}
6
7# running with `sudo` is required to be
8# able running the actual commands as the
9# original user.
10
11export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
12
13export RESULT=
14export NAMESPACE_NUM=0
15export INTERFACE_NUM=0
16
17netjail_next_namespace() {
18 local NUM=$NAMESPACE_NUM
19 NAMESPACE_NUM=$(($NAMESPACE_NUM + 1))
20 RESULT=$NUM
21}
22
23netjail_next_interface() {
24 local NUM=$INTERFACE_NUM
25 INTERFACE_NUM=$(($INTERFACE_NUM + 1))
26 RESULT=$NUM
27}
28
29netjail_opt() {
30 local OPT=$1
31 shift 1
32
33 INDEX=1
34
35 while [ $# -gt 0 ]; do
36 if [ "$1" = "$OPT" ]; then
37 RESULT=$INDEX
38 return
39 fi
40
41 INDEX=$(($INDEX + 1))
42 shift 1
43 done
44
45 RESULT=0
46}
47
48netjail_opts() {
49 local OPT=$1
50 local DEF=$2
51 shift 2
52
53 while [ $# -gt 0 ]; do
54 if [ "$1" = "$OPT" ]; then
55 printf "$2"
56 return
57 fi
58
59 shift 1
60 done
61
62 RESULT="$DEF"
63}
64
65netjail_check() {
66 local NODE_COUNT=$1
67 local FD_COUNT=$(($(ls /proc/self/fd | wc -w) - 4))
68
69 # quit if `$FD_COUNT < ($LOCAL_M * $GLOBAL_N * 2)`:
70 # the script also requires `sudo -C ($FD_COUNT + 4)`
71 # so you need 'Defaults closefrom_override' in the
72 # sudoers file.
73
74 if [ $FD_COUNT -lt $(($NODE_COUNT * 2)) ]; then
75 echo "File descriptors do not match requirements!" >&2
76 exit 1
77 fi
78}
79
80netjail_check_bin() {
81 local PROGRAM=$1
82 local MATCH=$(ls $(echo $PATH | tr ":" "\n") | grep "^$PROGRAM\$" | tr "\n" " " | awk '{ print $1 }')
83
84 # quit if the required binary $PROGRAM can not be
85 # found in the used $PATH.
86
87 if [ "$MATCH" != "$PROGRAM" ]; then
88 echo "Required binary not found: $PROGRAM" >&2
89 exit 1
90 fi
91}
92
93netjail_bridge() {
94 netjail_next_interface
95 local NUM=$RESULT
96 local BRIDGE=$(printf "%06x-%08x" $PREFIX $NUM)
97
98 ip link add $BRIDGE type bridge
99 ip link set dev $BRIDGE up
100
101 RESULT=$BRIDGE
102}
103
104netjail_bridge_name() {
105 netjail_next_interface
106 local NUM=$RESULT
107 local BRIDGE=$(printf "%06x-%08x" $PREFIX $NUM)
108
109 RESULT=$BRIDGE
110}
111
112netjail_bridge_clear() {
113 local BRIDGE=$1
114
115 ip link delete $BRIDGE
116}
117
118netjail_node() {
119 netjail_next_namespace
120 local NUM=$RESULT
121 local NODE=$(printf "%06x-%08x" $PREFIX $NUM)
122
123 ip netns add $NODE
124
125 RESULT=$NODE
126}
127
128netjail_node_name() {
129 netjail_next_namespace
130 local NUM=$RESULT
131 local NODE=$(printf "%06x-%08x" $PREFIX $NUM)
132
133 RESULT=$NODE
134}
135
136netjail_node_clear() {
137 local NODE=$1
138
139 ip netns delete $NODE
140}
141
142netjail_node_link_bridge() {
143 local NODE=$1
144 local BRIDGE=$2
145 local ADDRESS=$3
146 local MASK=$4
147
148 netjail_next_interface
149 local NUM_IF=$RESULT
150 netjail_next_interface
151 local NUM_BR=$RESULT
152
153 local LINK_IF=$(printf "%06x-%08x" $PREFIX $NUM_IF)
154 local LINK_BR=$(printf "%06x-%08x" $PREFIX $NUM_BR)
155
156 ip link add $LINK_IF type veth peer name $LINK_BR
157 ip link set $LINK_IF netns $NODE
158 ip link set $LINK_BR master $BRIDGE
159
160 ip -n $NODE addr add "$ADDRESS/$MASK" dev $LINK_IF
161 ip -n $NODE link set $LINK_IF up
162 ip -n $NODE link set up dev lo
163
164 ip link set $LINK_BR up
165
166 RESULT=$LINK_BR
167}
168
169netjail_node_link_bridge_name() {
170
171 netjail_next_interface
172 netjail_next_interface
173 local NUM_BR=$RESULT
174
175 local LINK_BR=$(printf "%06x-%08x" $PREFIX $NUM_BR)
176
177 RESULT=$LINK_BR
178}
179
180netjail_node_unlink_bridge() {
181 local LINK_BR=$1
182
183 ip link delete $LINK_BR
184}
185
186netjail_node_add_nat() {
187 local NODE=$1
188 local ADDRESS=$2
189 local MASK=$3
190
191 ip netns exec $NODE iptables -t nat -A POSTROUTING -s "$ADDRESS/$MASK" -j MASQUERADE
192}
193
194netjail_node_add_default() {
195 local NODE=$1
196 local ADDRESS=$2
197
198 ip -n $NODE route add default via $ADDRESS
199}
200
201netjail_node_exec() {
202 JAILOR=${SUDO_USER:?must run in sudo}
203 local NODE=$1
204 local FD_IN=$2
205 local FD_OUT=$3
206 shift 3
207
208 ip netns exec $NODE sudo -u $JAILOR -- $@ 1>& $FD_OUT 0<& $FD_IN
209}
210
211netjail_node_exec_without_fds() {
212 JAILOR=${SUDO_USER:?must run in sudo}
213 NODE=$1
214 shift 1
215
216 ip netns exec $NODE sudo -u $JAILOR -- $@
217}
218
219netjail_node_exec_without_fds_and_sudo() {
220 NODE=$1
221 shift 1
222
223 ip netns exec $NODE $@
224}
225
226netjail_kill() {
227 local PID=$1
228 local MATCH=$(ps --pid $PID | awk "{ if ( \$1 == $PID ) { print \$1 } }" | wc -l)
229
230 if [ $MATCH -gt 0 ]; then
231 kill -n 19 $PID
232
233 for CHILD in $(ps -o pid,ppid -ax | awk "{ if ( \$2 == $PID ) { print \$1 } }"); do
234 netjail_kill $CHILD
235 done
236
237 kill $PID
238 fi
239}
240
241netjail_killall() {
242 if [ $# -gt 0 ]; then
243 local PIDS=$1
244
245 for PID in $PIDS; do
246 netjail_kill $PID
247 done
248 fi
249}
250
251netjail_waitall() {
252 if [ $# -gt 0 ]; then
253 local PIDS=$1
254
255 for PID in $PIDS; do
256 wait $PID
257 done
258 fi
259}
260
diff --git a/src/testing/netjail_exec.sh b/src/testing/netjail_exec.sh
deleted file mode 100755
index 17a7caaac..000000000
--- a/src/testing/netjail_exec.sh
+++ /dev/null
@@ -1,16 +0,0 @@
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_exec_v2.sh b/src/testing/netjail_exec_v2.sh
deleted file mode 100755
index 597baad20..000000000
--- a/src/testing/netjail_exec_v2.sh
+++ /dev/null
@@ -1,14 +0,0 @@
1#!/bin/sh
2. "./../testing/netjail_core_v2.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=$6
13
14netjail_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
deleted file mode 100755
index 0984a3c42..000000000
--- a/src/testing/netjail_start.sh
+++ /dev/null
@@ -1,52 +0,0 @@
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_start_v2.sh b/src/testing/netjail_start_v2.sh
deleted file mode 100755
index dd1f2ad93..000000000
--- a/src/testing/netjail_start_v2.sh
+++ /dev/null
@@ -1,74 +0,0 @@
1#!/bin/bash
2. "./../testing/netjail_core_v2.sh"
3. "./../testing/topo.sh"
4
5set -eu
6set -x
7
8export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
9
10filename=$1
11PREFIX=$2
12
13read_topology $filename
14
15shift 2
16
17LOCAL_GROUP="192.168.15"
18GLOBAL_GROUP="92.68.150"
19KNOWN_GROUP="92.68.151"
20
21
22echo "Start [local: $LOCAL_GROUP.0/24, global: $GLOBAL_GROUP.0/16]"
23
24netjail_bridge
25NETWORK_NET=$RESULT
26
27for X in $(seq $KNOWN); do
28 netjail_node
29 KNOWN_NODES[$X]=$RESULT
30 netjail_node_link_bridge ${KNOWN_NODES[$X]} $NETWORK_NET "$KNOWN_GROUP.$X" 16
31 KNOWN_LINKS[$X]=$RESULT
32done
33
34declare -A NODES
35declare -A NODE_LINKS
36
37for N in $(seq $GLOBAL_N); do
38 netjail_node
39 ROUTERS[$N]=$RESULT
40 netjail_node_link_bridge ${ROUTERS[$N]} $NETWORK_NET "$GLOBAL_GROUP.$N" 16
41 NETWORK_LINKS[$N]=$RESULT
42 netjail_bridge
43 ROUTER_NETS[$N]=$RESULT
44
45 for M in $(seq $LOCAL_M); do
46 netjail_node
47 NODES[$N,$M]=$RESULT
48 netjail_node_link_bridge ${NODES[$N,$M]} ${ROUTER_NETS[$N]} "$LOCAL_GROUP.$M" 24
49 NODE_LINKS[$N,$M]=$RESULT
50 done
51
52 ROUTER_ADDR="$LOCAL_GROUP.$(($LOCAL_M+1))"
53 netjail_node_link_bridge ${ROUTERS[$N]} ${ROUTER_NETS[$N]} $ROUTER_ADDR 24
54 ROUTER_LINKS[$N]=$RESULT
55
56 netjail_node_add_nat ${ROUTERS[$N]} $ROUTER_ADDR 24
57
58 for M in $(seq $LOCAL_M); do
59 netjail_node_add_default ${NODES[$N,$M]} $ROUTER_ADDR
60 done
61
62 # TODO Topology configuration must be enhanced to configure forwarding to more than one subnet node via different ports.
63
64 if [ "1" == "${R_TCP[$N]}" ]
65 then
66 ip netns exec ${ROUTERS[$N]} iptables -t nat -A PREROUTING -p tcp -d $GLOBAL_GROUP.$N --dport 60002 -j DNAT --to $LOCAL_GROUP.1
67 ip netns exec ${ROUTERS[$N]} iptables -A FORWARD -d $LOCAL_GROUP.1 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
68 fi
69 if [ "1" == "${R_UDP[$N]}" ]
70 then
71 ip netns exec ${ROUTERS[$N]} iptables -t nat -A PREROUTING -p udp -d $GLOBAL_GROUP.$N --dport 60002 -j DNAT --to $LOCAL_GROUP.1
72 ip netns exec ${ROUTERS[$N]} iptables -A FORWARD -d $LOCAL_GROUP.1 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
73 fi
74done
diff --git a/src/testing/netjail_stop.sh b/src/testing/netjail_stop.sh
deleted file mode 100755
index 08f68cf7f..000000000
--- a/src/testing/netjail_stop.sh
+++ /dev/null
@@ -1,26 +0,0 @@
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/netjail_stop_v2.sh b/src/testing/netjail_stop_v2.sh
deleted file mode 100755
index 6e9fd1ccc..000000000
--- a/src/testing/netjail_stop_v2.sh
+++ /dev/null
@@ -1,59 +0,0 @@
1#!/bin/bash
2. "./../testing/netjail_core_v2.sh"
3. "./../testing/topo.sh"
4
5set -eu
6set -x
7
8export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
9
10filename=$1
11PREFIX=$2
12
13read_topology $filename
14
15declare -A NODES
16declare -A NODE_LINKS
17
18netjail_bridge_name
19NETWORK_NET=$RESULT
20
21for X in $(seq $KNOWN); do
22 netjail_node_name
23 KNOWN_NODES[$X]=$RESULT
24 netjail_node_link_bridge_name
25 KNOWN_LINKS[$X]=$RESULT
26 netjail_node_unlink_bridge ${KNOWN_LINKS[$X]}
27 netjail_node_clear ${KNOWN_NODES[$X]}
28done
29
30for N in $(seq $GLOBAL_N); do
31 netjail_node_name
32 ROUTERS[$N]=$RESULT
33 netjail_node_link_bridge_name
34 NETWORK_LINKS[$N]=$RESULT
35 netjail_bridge_name
36 ROUTER_NETS[$N]=$RESULT
37 netjail_node_link_bridge_name
38 ROUTER_LINKS[$N]=$RESULT
39
40 netjail_node_unlink_bridge ${ROUTER_LINKS[$N]}
41
42 for M in $(seq $LOCAL_M); do
43 netjail_node_name
44 NODES[$N,$M]=$RESULT
45 netjail_node_link_bridge_name
46 NODE_LINKS[$N,$M]=$RESULT
47 netjail_node_unlink_bridge ${NODE_LINKS[$N,$M]}
48 netjail_node_clear ${NODES[$N,$M]}
49 done
50
51
52 netjail_bridge_clear ${ROUTER_NETS[$N]}
53 netjail_node_unlink_bridge ${NETWORK_LINKS[$N]}
54 netjail_node_clear ${ROUTERS[$N]}
55done
56
57netjail_bridge_clear $NETWORK_NET
58
59echo "Done"
diff --git a/src/testing/test_testing_api_cmd_netjail.c b/src/testing/test_testing_api_cmd_netjail.c
deleted file mode 100644
index aeddfb7c9..000000000
--- a/src/testing/test_testing_api_cmd_netjail.c
+++ /dev/null
@@ -1,87 +0,0 @@
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 * Return value of the test.
33 *
34 */
35static unsigned int rv = 0;
36
37
38/**
39 * Main function to run the test cases.
40 *
41 * @param cls not used.
42 *
43 */
44static void
45run (void *cls)
46{
47 struct GNUNET_TESTING_Command commands[] = {
48 GNUNET_TESTING_cmd_netjail_start ("netjail-start-1",
49 "2",
50 "2"),
51 GNUNET_TESTING_cmd_netjail_start_testing_system ("netjail-start-testbed-1",
52 "2",
53 "2",
54 "libgnunet_plugin_testcmd",
55 &rv),
56 GNUNET_TESTING_cmd_stop_testing_system ("stop-testbed",
57 "netjail-start-testbed-1",
58 "2",
59 "2"),
60 GNUNET_TESTING_cmd_netjail_stop ("netjail-stop-1",
61 "2",
62 "2"),
63 GNUNET_TESTING_cmd_end ()
64 };
65
66 GNUNET_TESTING_run (NULL,
67 commands,
68 GNUNET_TIME_UNIT_FOREVER_REL);
69}
70
71
72int
73main (int argc,
74 char *const *argv)
75{
76 int rv = 0;
77
78 GNUNET_log_setup ("test-netjail",
79 "DEBUG",
80 NULL);
81 GNUNET_SCHEDULER_run (&run,
82 NULL);
83
84 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
85 "Test finished!\n");
86 return rv;
87}
diff --git a/src/testing/test_testing_defaults.conf b/src/testing/test_testing_defaults.conf
deleted file mode 100644
index 2e7c39113..000000000
--- a/src/testing/test_testing_defaults.conf
+++ /dev/null
@@ -1,25 +0,0 @@
1[PATHS]
2GNUNET_TEST_HOME = $GNUNET_TMP/test-gnunet-testing/
3
4[transport]
5PLUGINS = tcp
6
7[transport-tcp]
8TESTING_IGNORE_KEYS = SOMETHING;KEY1;ACCEPT_FROM;
9
10[transport-tcp]
11BINDTO = 127.0.0.1
12
13[nat]
14DISABLEV6 = YES
15ENABLE_UPNP = NO
16BEHIND_NAT = NO
17ALLOW_NAT = NO
18INTERNAL_ADDRESS = 127.0.0.1
19EXTERNAL_ADDRESS = 127.0.0.1
20USE_LOCALADDR = NO
21
22
23[rps]
24START_ON_DEMAND = NO
25IMMEDIATE_START = NO
diff --git a/src/testing/test_testing_hello_world.c b/src/testing/test_testing_hello_world.c
deleted file mode 100644
index 6300e26a4..000000000
--- a/src/testing/test_testing_hello_world.c
+++ /dev/null
@@ -1,68 +0,0 @@
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_testing_hello_world.c
23 * @brief hello world test case
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_testing_ng_lib.h"
28#include "gnunet_util_lib.h"
29
30/**
31 * Main function to run the test cases.
32 *
33 * @param cls not used.
34 *
35 */
36static void
37run (void *cls)
38{
39 (void *) cls;
40 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
41
42 struct GNUNET_TESTING_Command commands[] = {
43 GNUNET_TESTING_cmd_hello_world_birth ("hello-world-birth-0",
44 &now),
45 GNUNET_TESTING_cmd_hello_world ("hello-world-0","hello-world-birth-0",""),
46 GNUNET_TESTING_cmd_end ()
47 };
48
49 GNUNET_TESTING_run (NULL,
50 commands,
51 GNUNET_TIME_UNIT_FOREVER_REL);
52}
53
54int
55main (int argc,
56 char *const *argv)
57{
58 int rv = 0;
59
60 GNUNET_log_setup ("test-hello-world",
61 "DEBUG",
62 NULL);
63
64 GNUNET_SCHEDULER_run (&run,
65 NULL);
66
67 return rv;
68}
diff --git a/src/testing/test_testing_peerstartup.c b/src/testing/test_testing_peerstartup.c
deleted file mode 100644
index 25cbb2a9f..000000000
--- a/src/testing/test_testing_peerstartup.c
+++ /dev/null
@@ -1,143 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2008, 2009, 2012 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_testing_new_peerstartup.c
23 * @brief test case for testing peer startup and shutdown using new testing
24 * library
25 * @author Sree Harsha Totakura
26 */
27
28#include "platform.h"
29#include "gnunet_util_lib.h"
30#include "gnunet_testing_lib.h"
31
32#define LOG(kind, ...) \
33 GNUNET_log (kind, __VA_ARGS__)
34
35/**
36 * The status of the test
37 */
38int status;
39
40/**
41 * The testing context
42 */
43struct TestingContext
44{
45 /**
46 * The testing system
47 */
48 struct GNUNET_TESTING_System *system;
49
50 /**
51 * The peer which has been started by the testing system
52 */
53 struct GNUNET_TESTING_Peer *peer;
54
55 /**
56 * The running configuration of the peer
57 */
58 struct GNUNET_CONFIGURATION_Handle *cfg;
59};
60
61
62/**
63 * Task for shutdown
64 *
65 * @param cls the testing context
66 */
67static void
68do_shutdown (void *cls)
69{
70 struct TestingContext *test_ctx = cls;
71
72 GNUNET_assert (NULL != test_ctx);
73 if (NULL != test_ctx->peer)
74 {
75 (void) GNUNET_TESTING_peer_stop (test_ctx->peer);
76 GNUNET_TESTING_peer_destroy (test_ctx->peer);
77 }
78 if (NULL != test_ctx->cfg)
79 GNUNET_CONFIGURATION_destroy (test_ctx->cfg);
80 if (NULL != test_ctx->system)
81 GNUNET_TESTING_system_destroy (test_ctx->system, GNUNET_YES);
82 GNUNET_free (test_ctx);
83}
84
85
86/**
87 * Main point of test execution
88 */
89static void
90run (void *cls, char *const *args, const char *cfgfile,
91 const struct GNUNET_CONFIGURATION_Handle *cfg)
92{
93 struct TestingContext *test_ctx;
94 char *emsg;
95 struct GNUNET_PeerIdentity id;
96
97 test_ctx = GNUNET_new (struct TestingContext);
98 test_ctx->system =
99 GNUNET_TESTING_system_create ("test-gnunet-testing",
100 "127.0.0.1", NULL, NULL);
101 emsg = NULL;
102 if (NULL == test_ctx->system)
103 goto end;
104 test_ctx->cfg = GNUNET_CONFIGURATION_dup (cfg);
105 test_ctx->peer =
106 GNUNET_TESTING_peer_configure (test_ctx->system,
107 test_ctx->cfg,
108 0, &id, &emsg);
109 if (NULL == test_ctx->peer)
110 {
111 if (NULL != emsg)
112 printf ("Test failed upon error: %s", emsg);
113 goto end;
114 }
115 if (GNUNET_OK != GNUNET_TESTING_peer_start (test_ctx->peer))
116 goto end;
117 status = GNUNET_OK;
118
119end:
120 GNUNET_SCHEDULER_add_now (&do_shutdown, test_ctx);
121 GNUNET_free (emsg);
122}
123
124
125int
126main (int argc, char *argv[])
127{
128 struct GNUNET_GETOPT_CommandLineOption options[] = {
129 GNUNET_GETOPT_OPTION_END
130 };
131
132 status = GNUNET_SYSERR;
133 if (GNUNET_OK !=
134 GNUNET_PROGRAM_run (argc, argv,
135 "test_testing_peerstartup",
136 "test case for peerstartup using new testing library",
137 options, &run, NULL))
138 return 1;
139 return (GNUNET_OK == status) ? 0 : 1;
140}
141
142
143/* end of test_testing_peerstartup.c */
diff --git a/src/testing/test_testing_peerstartup2.c b/src/testing/test_testing_peerstartup2.c
deleted file mode 100644
index 8d357cb08..000000000
--- a/src/testing/test_testing_peerstartup2.c
+++ /dev/null
@@ -1,222 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2008, 2009, 2012 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_testing_new_peerstartup.c
23 * @brief test case for testing peer startup and shutdown using new testing
24 * library
25 * @author Sree Harsha Totakura
26 */
27
28#include "platform.h"
29#include "gnunet_util_lib.h"
30#include "gnunet_testing_lib.h"
31
32#define LOG(kind, ...) \
33 GNUNET_log (kind, __VA_ARGS__)
34
35
36#define FAIL_TEST(cond) \
37 do { \
38 if (! (cond)) { \
39 GNUNET_break (0); \
40 if (GNUNET_OK == status) { \
41 status = GNUNET_SYSERR; \
42 } \
43 } \
44 } while (0) \
45
46
47/**
48 * The status of the test
49 */
50int status;
51
52/**
53 * The testing context
54 */
55struct TestingContext
56{
57 /**
58 * The testing system
59 */
60 struct GNUNET_TESTING_System *system;
61
62 /**
63 * The peer which has been started by the testing system
64 */
65 struct GNUNET_TESTING_Peer *peer;
66
67 /**
68 * The running configuration of the peer
69 */
70 struct GNUNET_CONFIGURATION_Handle *cfg;
71
72 /**
73 * State
74 */
75 enum
76 {
77 PEER_INIT,
78
79 PEER_STARTED,
80
81 PEER_STOPPED
82 } state;
83};
84
85
86static void
87do_shutdown2 (void *cls)
88{
89 struct TestingContext *test_ctx = cls;
90
91 if (NULL != test_ctx->peer)
92 GNUNET_TESTING_peer_destroy (test_ctx->peer);
93 if (NULL != test_ctx->cfg)
94 GNUNET_CONFIGURATION_destroy (test_ctx->cfg);
95 if (NULL != test_ctx->system)
96 GNUNET_TESTING_system_destroy (test_ctx->system, GNUNET_YES);
97 GNUNET_free (test_ctx);
98}
99
100
101/**
102 * Task for shutdown
103 *
104 * @param cls the testing context
105 */
106static void
107do_shutdown (void *cls);
108
109
110static void
111peer_status_cb (void *cls, struct GNUNET_TESTING_Peer *peer, int success)
112{
113 struct TestingContext *test_ctx = cls;
114
115 switch (test_ctx->state)
116 {
117 case PEER_INIT:
118 FAIL_TEST (0);
119 break;
120
121 case PEER_STARTED:
122 FAIL_TEST (GNUNET_YES == success);
123 test_ctx->state = PEER_STOPPED;
124 GNUNET_SCHEDULER_add_now (&do_shutdown2, cls);
125 break;
126
127 case PEER_STOPPED:
128 FAIL_TEST (0);
129 }
130}
131
132
133/**
134 * Task for shutdown
135 *
136 * @param cls the testing context
137 */
138static void
139do_shutdown (void *cls)
140{
141 struct TestingContext *test_ctx = cls;
142
143 GNUNET_assert (NULL != test_ctx);
144 if (NULL != test_ctx->peer)
145 {
146 FAIL_TEST (GNUNET_OK ==
147 GNUNET_TESTING_peer_stop_async (test_ctx->peer,
148 &peer_status_cb,
149 test_ctx));
150 }
151 else
152 do_shutdown2 (test_ctx);
153}
154
155
156/**
157 * Main point of test execution
158 */
159static void
160run (void *cls, char *const *args, const char *cfgfile,
161 const struct GNUNET_CONFIGURATION_Handle *cfg)
162{
163 struct TestingContext *test_ctx;
164 char *emsg;
165 struct GNUNET_PeerIdentity id;
166
167 test_ctx = GNUNET_new (struct TestingContext);
168 test_ctx->system =
169 GNUNET_TESTING_system_create ("test-gnunet-testing",
170 "127.0.0.1", NULL, NULL);
171 emsg = NULL;
172 if (NULL == test_ctx->system)
173 goto end;
174 test_ctx->cfg = GNUNET_CONFIGURATION_dup (cfg);
175 test_ctx->peer =
176 GNUNET_TESTING_peer_configure (test_ctx->system,
177 test_ctx->cfg,
178 0, &id, &emsg);
179 if (NULL == test_ctx->peer)
180 {
181 if (NULL != emsg)
182 printf ("Test failed upon error: %s", emsg);
183 goto end;
184 }
185 if (GNUNET_OK != GNUNET_TESTING_peer_start (test_ctx->peer))
186 goto end;
187 test_ctx->state = PEER_STARTED;
188 FAIL_TEST (GNUNET_OK ==
189 GNUNET_TESTING_peer_stop_async (test_ctx->peer,
190 &peer_status_cb,
191 test_ctx));
192 GNUNET_TESTING_peer_stop_async_cancel (test_ctx->peer);
193 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
194 &do_shutdown, test_ctx);
195 return;
196
197end:
198 FAIL_TEST (0);
199 GNUNET_SCHEDULER_add_now (&do_shutdown, test_ctx);
200 GNUNET_free (emsg);
201}
202
203
204int
205main (int argc, char *argv[])
206{
207 struct GNUNET_GETOPT_CommandLineOption options[] = {
208 GNUNET_GETOPT_OPTION_END
209 };
210
211 status = GNUNET_OK;
212 if (GNUNET_OK !=
213 GNUNET_PROGRAM_run (argc, argv,
214 "test_testing_new_peerstartup",
215 "test case for peerstartup using new testing library",
216 options, &run, NULL))
217 return 1;
218 return (GNUNET_OK == status) ? 0 : 1;
219}
220
221
222/* end of test_testing_peerstartup.c */
diff --git a/src/testing/test_testing_plugin_testcmd.c b/src/testing/test_testing_plugin_testcmd.c
deleted file mode 100644
index 444272fcd..000000000
--- a/src/testing/test_testing_plugin_testcmd.c
+++ /dev/null
@@ -1,116 +0,0 @@
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/test_testing_portreservation.c b/src/testing/test_testing_portreservation.c
deleted file mode 100644
index df3d8d523..000000000
--- a/src/testing/test_testing_portreservation.c
+++ /dev/null
@@ -1,105 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2008, 2009, 2012 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_testing_new_portreservation.c
23 * @brief test case for testing port reservation routines from the new testing
24 * library API
25 * @author Sree Harsha Totakura
26 */
27
28#include "platform.h"
29#include "gnunet_util_lib.h"
30#include "gnunet_testing_lib.h"
31
32#define LOG(kind, ...) \
33 GNUNET_log (kind, __VA_ARGS__)
34
35/**
36 * The status of the test
37 */
38int status;
39
40/**
41 * Main point of test execution
42 */
43static void
44run (void *cls, char *const *args, const char *cfgfile,
45 const struct GNUNET_CONFIGURATION_Handle *cfg)
46{
47 struct GNUNET_TESTING_System *system;
48 uint16_t new_port1;
49 uint16_t new_port2;
50 uint16_t old_port1;
51
52 system = GNUNET_TESTING_system_create ("/tmp/gnunet-testing-new",
53 "localhost", NULL, NULL);
54 GNUNET_assert (NULL != system);
55 new_port1 = GNUNET_TESTING_reserve_port (system);
56 LOG (GNUNET_ERROR_TYPE_DEBUG,
57 "Reserved TCP port %u\n", new_port1);
58 if (0 == new_port1)
59 goto end;
60 new_port2 = GNUNET_TESTING_reserve_port (system);
61 LOG (GNUNET_ERROR_TYPE_DEBUG,
62 "Reserved TCP port %u\n", new_port2);
63 if (0 == new_port2)
64 goto end;
65 GNUNET_assert (new_port1 != new_port2);
66 GNUNET_TESTING_release_port (system, new_port1);
67 old_port1 = new_port1;
68 new_port1 = 0;
69 new_port1 = GNUNET_TESTING_reserve_port (system);
70 LOG (GNUNET_ERROR_TYPE_DEBUG,
71 "Reserved TCP port %u\n", new_port1);
72 GNUNET_assert (0 != new_port1);
73 GNUNET_assert (old_port1 == new_port1);
74 GNUNET_TESTING_release_port (system, new_port1);
75 GNUNET_TESTING_release_port (system, new_port2);
76 status = GNUNET_OK;
77
78end:
79 GNUNET_TESTING_system_destroy (system, GNUNET_YES);
80}
81
82
83int
84main (int argc, char *argv[])
85{
86 struct GNUNET_GETOPT_CommandLineOption options[] = {
87 GNUNET_GETOPT_OPTION_END
88 };
89
90 status = GNUNET_SYSERR;
91 if (GNUNET_OK !=
92 GNUNET_PROGRAM_run (argc,
93 argv,
94 "test_testing_new_portreservation",
95 "test case for testing port reservation routines"
96 " from the new testing library API",
97 options,
98 &run,
99 NULL))
100 return 1;
101 return (GNUNET_OK == status) ? 0 : 1;
102}
103
104
105/* end of test_testing_portreservation.c */
diff --git a/src/testing/test_testing_servicestartup.c b/src/testing/test_testing_servicestartup.c
deleted file mode 100644
index 83458898b..000000000
--- a/src/testing/test_testing_servicestartup.c
+++ /dev/null
@@ -1,75 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2008, 2009, 2012 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_testing_new_servicestartup.c
23 * @brief test case for testing service startup using new testing API
24 * @author Sree Harsha Totakura
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_testing_lib.h"
29
30
31#define LOG(kind, ...) \
32 GNUNET_log (kind, __VA_ARGS__)
33
34
35/**
36 * Global test status
37 */
38static int test_success;
39
40
41/**
42 * The testing callback function
43 *
44 * @param cls NULL
45 * @param cfg the configuration with which the current testing service is run
46 */
47static void
48test_run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg,
49 struct GNUNET_TESTING_Peer *peer)
50{
51 GNUNET_assert (NULL == cls);
52 GNUNET_assert (NULL != cfg);
53 LOG (GNUNET_ERROR_TYPE_DEBUG, "Service arm started successfully\n");
54 test_success = GNUNET_YES;
55 GNUNET_SCHEDULER_shutdown ();
56}
57
58
59/**
60 * The main point of execution
61 */
62int
63main (int argc, char *argv[])
64{
65 test_success = GNUNET_NO;
66 GNUNET_assert (0 == GNUNET_TESTING_service_run ("test-testing-servicestartup",
67 "arm",
68 "test_testing_defaults.conf",
69 &test_run,
70 NULL));
71 return (GNUNET_YES == test_success) ? 0 : 1;
72}
73
74
75/* end of test_testing_servicestartup.c */
diff --git a/src/testing/test_testing_sharedservices.c b/src/testing/test_testing_sharedservices.c
deleted file mode 100644
index d2f760d7a..000000000
--- a/src/testing/test_testing_sharedservices.c
+++ /dev/null
@@ -1,167 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2008, 2009, 2012 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_testing_sharedservices.c
23 * @brief test case for testing service sharing among peers started by testing
24 * @author Sree Harsha Totakura <sreeharsha@totakura.in>
25 */
26
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_testing_lib.h"
30
31#define LOG(kind, ...) \
32 GNUNET_log (kind, __VA_ARGS__)
33
34#define NUM_PEERS 4
35
36/**
37 * The status of the test
38 */
39int status;
40
41/**
42 * The testing context
43 */
44struct TestingContext
45{
46 /**
47 * The testing system
48 */
49 struct GNUNET_TESTING_System *system;
50
51 /**
52 * The peer which has been started by the testing system
53 */
54 struct GNUNET_TESTING_Peer *peers[NUM_PEERS];
55
56 /**
57 * The running configuration of the peer
58 */
59 struct GNUNET_CONFIGURATION_Handle *cfg;
60};
61
62
63/**
64 * Task for shutdown
65 *
66 * @param cls the testing context
67 */
68static void
69do_shutdown (void *cls)
70{
71 struct TestingContext *test_ctx = cls;
72 struct GNUNET_TESTING_Peer *peer;
73 unsigned int cnt;
74
75 GNUNET_assert (NULL != test_ctx);
76 for (cnt = 0; cnt < NUM_PEERS; cnt++)
77 {
78 peer = test_ctx->peers[cnt];
79 if (NULL == peer)
80 continue;
81 (void) GNUNET_TESTING_peer_stop (peer);
82 GNUNET_TESTING_peer_destroy (peer);
83 }
84 if (NULL != test_ctx->cfg)
85 GNUNET_CONFIGURATION_destroy (test_ctx->cfg);
86 if (NULL != test_ctx->system)
87 GNUNET_TESTING_system_destroy (test_ctx->system, GNUNET_YES);
88 GNUNET_free (test_ctx);
89}
90
91
92/**
93 * Main point of test execution
94 */
95static void
96run (void *cls, char *const *args, const char *cfgfile,
97 const struct GNUNET_CONFIGURATION_Handle *cfg)
98{
99 struct TestingContext *test_ctx;
100 char *emsg;
101 struct GNUNET_PeerIdentity id;
102 struct GNUNET_TESTING_SharedService ss[] = {
103 { "peerinfo", cfg, 2 },
104 { NULL, NULL, 0 }
105 };
106 struct GNUNET_TESTING_Peer *peer;
107 unsigned int cnt;
108
109 test_ctx = GNUNET_new (struct TestingContext);
110 test_ctx->system =
111 GNUNET_TESTING_system_create ("test-gnunet-testing",
112 "127.0.0.1", NULL, ss);
113 emsg = NULL;
114 if (NULL == test_ctx->system)
115 goto end;
116 test_ctx->cfg = GNUNET_CONFIGURATION_dup (cfg);
117 for (cnt = 0; cnt < NUM_PEERS; cnt++)
118 {
119 peer = GNUNET_TESTING_peer_configure (test_ctx->system,
120 test_ctx->cfg,
121 0, &id, &emsg);
122 if (NULL == peer)
123 {
124 if (NULL != emsg)
125 printf ("Test failed upon error: %s", emsg);
126 goto end;
127 }
128 if (GNUNET_OK != GNUNET_TESTING_peer_start (peer))
129 {
130 GNUNET_TESTING_peer_destroy (peer);
131 goto end;
132 }
133 test_ctx->peers[cnt] = peer;
134 }
135 status = GNUNET_OK;
136 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
137 &do_shutdown, test_ctx);
138 return;
139
140end:
141 GNUNET_SCHEDULER_add_now (&do_shutdown, test_ctx);
142 GNUNET_free (emsg);
143}
144
145
146int
147main (int argc, char *argv[])
148{
149 struct GNUNET_GETOPT_CommandLineOption options[] = {
150 GNUNET_GETOPT_OPTION_END
151 };
152 char *const argv2[] = { "test_testing_sharedservices",
153 "-c", "test_testing_sharedservices.conf",
154 NULL };
155
156 status = GNUNET_SYSERR;
157 if (GNUNET_OK !=
158 GNUNET_PROGRAM_run ((sizeof(argv2) / sizeof(char *)) - 1, argv2,
159 "test_testing_sharedservices",
160 "test case for testing service sharing among peers started by testing",
161 options, &run, NULL))
162 return 1;
163 return (GNUNET_OK == status) ? 0 : 3;
164}
165
166
167/* end of test_testing_sharedservices.c */
diff --git a/src/testing/test_testing_sharedservices.conf b/src/testing/test_testing_sharedservices.conf
deleted file mode 100644
index 92eac7e71..000000000
--- a/src/testing/test_testing_sharedservices.conf
+++ /dev/null
@@ -1,30 +0,0 @@
1[PATHS]
2GNUNET_TEST_HOME = $GNUNET_TMP/test-gnunet-testing/
3
4[testbed-logger]
5PORT = 59132
6UNIXPATH = $GNUNET_RUNTIME_DIR/testbed-logger.sock
7DIR = $GNUNET_TMP/testbed-logger
8
9[transport]
10PLUGINS = tcp
11
12[transport-tcp]
13TESTING_IGNORE_KEYS = SOMETHING;KEY1;ACCEPT_FROM;
14
15[transport-tcp]
16BINDTO = 127.0.0.1
17
18[nat]
19DISABLEV6 = YES
20ENABLE_UPNP = NO
21BEHIND_NAT = NO
22ALLOW_NAT = NO
23INTERNAL_ADDRESS = 127.0.0.1
24EXTERNAL_ADDRESS = 127.0.0.1
25USE_LOCALADDR = NO
26
27
28[rps]
29START_ON_DEMAND = NO
30IMMEDIATE_START = NO
diff --git a/src/testing/testing.c b/src/testing/testing.c
deleted file mode 100644
index a11d404a5..000000000
--- a/src/testing/testing.c
+++ /dev/null
@@ -1,2284 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2008, 2009, 2012 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.c
23 * @brief convenience API for writing testcases for GNUnet
24 * Many testcases need to start and stop a peer/service
25 * and this library is supposed to make that easier
26 * for TESTCASES. Normal programs should always
27 * use functions from gnunet_{util,arm}_lib.h. This API is
28 * ONLY for writing testcases (or internal use of the testbed).
29 * @author Christian Grothoff
30 *
31 */
32#include "platform.h"
33#include "gnunet_util_lib.h"
34#include "gnunet_arm_service.h"
35#include "gnunet_testing_lib.h"
36#include "gnunet_testing_ng_lib.h"
37
38#define LOG(kind, ...) GNUNET_log_from (kind, "testing-api", __VA_ARGS__)
39
40
41/**
42 * Lowest port used for GNUnet testing. Should be high enough to not
43 * conflict with other applications running on the hosts but be low
44 * enough to not conflict with client-ports (typically starting around
45 * 32k).
46 */
47#define LOW_PORT 12000
48
49/**
50 * Highest port used for GNUnet testing. Should be low enough to not
51 * conflict with the port range for "local" ports (client apps; see
52 * /proc/sys/net/ipv4/ip_local_port_range on Linux for example).
53 */
54#define HIGH_PORT 56000
55
56
57struct SharedServiceInstance
58{
59 struct SharedService *ss;
60
61 char *cfg_fn;
62
63 struct GNUNET_OS_Process *proc;
64
65 char *unix_sock;
66
67 char *port_str;
68
69 unsigned int n_refs;
70};
71
72struct SharedService
73{
74 char *sname;
75
76 struct SharedServiceInstance **instances;
77
78 struct GNUNET_CONFIGURATION_Handle *cfg;
79
80 unsigned int n_peers;
81
82 unsigned int share;
83
84 unsigned int n_instances;
85};
86
87
88/**
89 * Handle for a system on which GNUnet peers are executed;
90 * a system is used for reserving unique paths and ports.
91 */
92struct GNUNET_TESTING_System
93{
94 /**
95 * Prefix (e.g. "/tmp/gnunet-testing/") we prepend to each
96 * GNUNET_HOME.
97 */
98 char *tmppath;
99
100 /**
101 * The trusted ip. Can either be a single ip address or a network address in
102 * CIDR notation.
103 */
104 char *trusted_ip;
105
106 /**
107 * our hostname
108 */
109 char *hostname;
110
111 /**
112 * Hostkeys data, contains "GNUNET_TESTING_HOSTKEYFILESIZE * total_hostkeys" bytes.
113 */
114 char *hostkeys_data;
115
116 /**
117 * memory map for @e hostkeys_data.
118 */
119 struct GNUNET_DISK_MapHandle *map;
120
121 struct SharedService **shared_services;
122
123 unsigned int n_shared_services;
124
125 /**
126 * Bitmap where each port that has already been reserved for some GNUnet peer
127 * is recorded. Note that we make no distinction between TCP and UDP ports
128 * and test if a port is already in use before assigning it to a peer/service.
129 * If we detect that a port is already in use, we also mark it in this bitmap.
130 * So all the bits that are zero merely indicate ports that MIGHT be available
131 * for peers.
132 */
133 uint32_t reserved_ports[65536 / 32];
134
135 /**
136 * Counter we use to make service home paths unique on this system;
137 * the full path consists of the tmppath and this number. Each
138 * UNIXPATH for a peer is also modified to include the respective
139 * path counter to ensure uniqueness. This field is incremented
140 * by one for each configured peer. Even if peers are destroyed,
141 * we never re-use path counters.
142 */
143 uint32_t path_counter;
144
145 /**
146 * The number of hostkeys
147 */
148 uint32_t total_hostkeys;
149
150 /**
151 * Lowest port we are allowed to use.
152 */
153 uint16_t lowport;
154
155 /**
156 * Highest port we are allowed to use.
157 */
158 uint16_t highport;
159};
160
161
162/**
163 * Handle for a GNUnet peer controlled by testing.
164 */
165struct GNUNET_TESTING_Peer
166{
167 /**
168 * The TESTING system associated with this peer
169 */
170 struct GNUNET_TESTING_System *system;
171
172 /**
173 * Path to the configuration file for this peer.
174 */
175 char *cfgfile;
176
177 /**
178 * Binary to be executed during 'GNUNET_TESTING_peer_start'.
179 * Typically 'gnunet-service-arm' (but can be set to a
180 * specific service by 'GNUNET_TESTING_service_run' if
181 * necessary).
182 */
183 char *main_binary;
184 char *args;
185
186 /**
187 * Handle to the running binary of the service, NULL if the
188 * peer/service is currently not running.
189 */
190 struct GNUNET_OS_Process *main_process;
191
192 /**
193 * The handle to the peer's ARM service
194 */
195 struct GNUNET_ARM_Handle *ah;
196
197 /**
198 * The config of the peer
199 */
200 struct GNUNET_CONFIGURATION_Handle *cfg;
201
202 /**
203 * The callback to call asynchronously when a peer is stopped
204 */
205 GNUNET_TESTING_PeerStopCallback cb;
206
207 /**
208 * The closure for the above callback
209 */
210 void *cb_cls;
211
212 /**
213 * The cached identity of this peer. Will be populated on call to
214 * GNUNET_TESTING_peer_get_identity()
215 */
216 struct GNUNET_PeerIdentity *id;
217
218 struct SharedServiceInstance **ss_instances;
219
220 /**
221 * Array of ports currently allocated to this peer. These ports will be
222 * released upon peer destroy and can be used by other peers which are
223 * configured after.
224 */
225 uint16_t *ports;
226
227 /**
228 * The number of ports in the above array
229 */
230 unsigned int nports;
231
232 /**
233 * The keynumber of this peer's hostkey
234 */
235 uint32_t key_number;
236};
237
238
239/**
240 * Testing includes a number of pre-created hostkeys for faster peer
241 * startup. This function loads such keys into memory from a file.
242 *
243 * @param system the testing system handle
244 * @return #GNUNET_OK on success; #GNUNET_SYSERR on error
245 */
246static int
247hostkeys_load (struct GNUNET_TESTING_System *system)
248{
249 uint64_t fs;
250 char *data_dir;
251 char *filename;
252 struct GNUNET_DISK_FileHandle *fd;
253
254 GNUNET_assert (NULL == system->hostkeys_data);
255 data_dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR);
256 GNUNET_asprintf (&filename, "%s/testing_hostkeys.ecc", data_dir);
257 GNUNET_free (data_dir);
258
259 if (GNUNET_YES != GNUNET_DISK_file_test (filename))
260 {
261 LOG (GNUNET_ERROR_TYPE_ERROR,
262 _ ("Hostkeys file not found: %s\n"),
263 filename);
264 GNUNET_free (filename);
265 return GNUNET_SYSERR;
266 }
267 /* Check hostkey file size, read entire thing into memory */
268 if (GNUNET_OK !=
269 GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES))
270 fs = 0;
271 if (0 == fs)
272 {
273 GNUNET_free (filename);
274 return GNUNET_SYSERR; /* File is empty */
275 }
276 if (0 != (fs % GNUNET_TESTING_HOSTKEYFILESIZE))
277 {
278 LOG (GNUNET_ERROR_TYPE_ERROR,
279 _ ("Incorrect hostkey file format: %s\n"),
280 filename);
281 GNUNET_free (filename);
282 return GNUNET_SYSERR;
283 }
284 fd = GNUNET_DISK_file_open (filename,
285 GNUNET_DISK_OPEN_READ,
286 GNUNET_DISK_PERM_NONE);
287 if (NULL == fd)
288 {
289 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", filename);
290 GNUNET_free (filename);
291 return GNUNET_SYSERR;
292 }
293 GNUNET_free (filename);
294 system->hostkeys_data =
295 GNUNET_DISK_file_map (fd, &system->map, GNUNET_DISK_MAP_TYPE_READ, fs);
296 GNUNET_DISK_file_close (fd);
297 if (NULL == system->hostkeys_data)
298 return GNUNET_SYSERR;
299 system->total_hostkeys = fs / GNUNET_TESTING_HOSTKEYFILESIZE;
300 return GNUNET_OK;
301}
302
303
304/**
305 * Function to remove the loaded hostkeys
306 *
307 * @param system the testing system handle
308 */
309static void
310hostkeys_unload (struct GNUNET_TESTING_System *system)
311{
312 GNUNET_break (NULL != system->hostkeys_data);
313 system->hostkeys_data = NULL;
314 GNUNET_DISK_file_unmap (system->map);
315 system->map = NULL;
316 system->hostkeys_data = NULL;
317 system->total_hostkeys = 0;
318}
319
320
321/**
322 * Function to iterate over options.
323 *
324 * @param cls closure
325 * @param section name of the section
326 * @param option name of the option
327 * @param value value of the option
328 */
329static void
330cfg_copy_iterator (void *cls,
331 const char *section,
332 const char *option,
333 const char *value)
334{
335 struct GNUNET_CONFIGURATION_Handle *cfg2 = cls;
336
337 GNUNET_CONFIGURATION_set_value_string (cfg2, section, option, value);
338}
339
340
341/**
342 * Create a system handle. There must only be one system
343 * handle per operating system.
344 *
345 * @param testdir only the directory name without any path. This is used for
346 * all service homes; the directory will be created in a temporary
347 * location depending on the underlying OS. This variable will be
348 * overridden with the value of the environmental variable
349 * GNUNET_TESTING_PREFIX, if it exists.
350 * @param trusted_ip the ip address which will be set as TRUSTED HOST in all
351 * service configurations generated to allow control connections from
352 * this ip. This can either be a single ip address or a network address
353 * in CIDR notation.
354 * @param hostname the hostname of the system we are using for testing; NULL for
355 * localhost
356 * @param shared_services NULL terminated array describing services that are to
357 * be shared among peers
358 * @param lowport lowest port number this system is allowed to allocate (inclusive)
359 * @param highport highest port number this system is allowed to allocate (exclusive)
360 * @return handle to this system, NULL on error
361 */
362struct GNUNET_TESTING_System *
363GNUNET_TESTING_system_create_with_portrange (
364 const char *testdir,
365 const char *trusted_ip,
366 const char *hostname,
367 const struct GNUNET_TESTING_SharedService *shared_services,
368 uint16_t lowport,
369 uint16_t highport)
370{
371 struct GNUNET_TESTING_System *system;
372 struct GNUNET_TESTING_SharedService tss;
373 struct SharedService *ss;
374 unsigned int cnt;
375
376 GNUNET_assert (NULL != testdir);
377 system = GNUNET_new (struct GNUNET_TESTING_System);
378 if (NULL == (system->tmppath = getenv (GNUNET_TESTING_PREFIX)))
379 system->tmppath = GNUNET_DISK_mkdtemp (testdir);
380 else
381 system->tmppath = GNUNET_strdup (system->tmppath);
382 system->lowport = lowport;
383 system->highport = highport;
384 if (NULL == system->tmppath)
385 {
386 GNUNET_free (system);
387 return NULL;
388 }
389 if (NULL != trusted_ip)
390 system->trusted_ip = GNUNET_strdup (trusted_ip);
391 if (NULL != hostname)
392 system->hostname = GNUNET_strdup (hostname);
393 if (GNUNET_OK != hostkeys_load (system))
394 {
395 GNUNET_TESTING_system_destroy (system, GNUNET_YES);
396 return NULL;
397 }
398 if (NULL == shared_services)
399 return system;
400 for (cnt = 0; NULL != shared_services[cnt].service; cnt++)
401 {
402 tss = shared_services[cnt];
403 ss = GNUNET_new (struct SharedService);
404 ss->sname = GNUNET_strdup (tss.service);
405 ss->cfg = GNUNET_CONFIGURATION_create ();
406 GNUNET_CONFIGURATION_iterate_section_values (tss.cfg,
407 ss->sname,
408 &cfg_copy_iterator,
409 ss->cfg);
410 GNUNET_CONFIGURATION_iterate_section_values (tss.cfg,
411 "TESTING",
412 &cfg_copy_iterator,
413 ss->cfg);
414 GNUNET_CONFIGURATION_iterate_section_values (tss.cfg,
415 "PATHS",
416 &cfg_copy_iterator,
417 ss->cfg);
418 ss->share = tss.share;
419 GNUNET_array_append (system->shared_services,
420 system->n_shared_services,
421 ss);
422 }
423 return system;
424}
425
426
427/**
428 * Create a system handle. There must only be one system handle per operating
429 * system. Uses a default range for allowed ports. Ports are still tested for
430 * availability.
431 *
432 * @param testdir only the directory name without any path. This is used for all
433 * service homes; the directory will be created in a temporary location
434 * depending on the underlying OS. This variable will be
435 * overridden with the value of the environmental variable
436 * GNUNET_TESTING_PREFIX, if it exists.
437 * @param trusted_ip the ip address which will be set as TRUSTED HOST in all
438 * service configurations generated to allow control connections from
439 * this ip. This can either be a single ip address or a network address
440 * in CIDR notation.
441 * @param hostname the hostname of the system we are using for testing; NULL for
442 * localhost
443 * @param shared_services NULL terminated array describing services that are to
444 * be shared among peers
445 * @return handle to this system, NULL on error
446 */
447struct GNUNET_TESTING_System *
448GNUNET_TESTING_system_create (
449 const char *testdir,
450 const char *trusted_ip,
451 const char *hostname,
452 const struct GNUNET_TESTING_SharedService *shared_services)
453{
454 return GNUNET_TESTING_system_create_with_portrange (testdir,
455 trusted_ip,
456 hostname,
457 shared_services,
458 LOW_PORT,
459 HIGH_PORT);
460}
461
462
463static void
464cleanup_shared_service_instance (struct SharedServiceInstance *i)
465{
466 if (NULL != i->cfg_fn)
467 {
468 (void) unlink (i->cfg_fn);
469 GNUNET_free (i->cfg_fn);
470 }
471 GNUNET_free (i->unix_sock);
472 GNUNET_free (i->port_str);
473 GNUNET_break (NULL == i->proc);
474 GNUNET_break (0 == i->n_refs);
475 GNUNET_free (i);
476}
477
478
479static int
480start_shared_service_instance (struct SharedServiceInstance *i)
481{
482 char *binary;
483 char *libexec_binary;
484
485 GNUNET_assert (NULL == i->proc);
486 GNUNET_assert (NULL != i->cfg_fn);
487 (void) GNUNET_asprintf (&binary, "gnunet-service-%s", i->ss->sname);
488 libexec_binary = GNUNET_OS_get_libexec_binary_path (binary);
489 GNUNET_free (binary);
490 i->proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
491 NULL,
492 NULL,
493 NULL,
494 libexec_binary,
495 libexec_binary,
496 "-c",
497 i->cfg_fn,
498 NULL);
499 GNUNET_free (libexec_binary);
500 if (NULL == i->proc)
501 return GNUNET_SYSERR;
502 return GNUNET_OK;
503}
504
505
506static void
507stop_shared_service_instance (struct SharedServiceInstance *i)
508{
509 GNUNET_break (0 == i->n_refs);
510 if (0 != GNUNET_OS_process_kill (i->proc, GNUNET_TERM_SIG))
511 LOG (GNUNET_ERROR_TYPE_WARNING,
512 "Killing shared service instance (%s) failed\n",
513 i->ss->sname);
514 (void) GNUNET_OS_process_wait (i->proc);
515 GNUNET_OS_process_destroy (i->proc);
516 i->proc = NULL;
517}
518
519
520/**
521 * Free system resources.
522 *
523 * @param system system to be freed
524 * @param remove_paths should the 'testdir' and all subdirectories
525 * be removed (clean up on shutdown)?
526 */
527void
528GNUNET_TESTING_system_destroy (struct GNUNET_TESTING_System *system,
529 int remove_paths)
530{
531 struct SharedService *ss;
532 struct SharedServiceInstance *i;
533 unsigned int ss_cnt;
534 unsigned int i_cnt;
535
536 if (NULL != system->hostkeys_data)
537 hostkeys_unload (system);
538 for (ss_cnt = 0; ss_cnt < system->n_shared_services; ss_cnt++)
539 {
540 ss = system->shared_services[ss_cnt];
541 for (i_cnt = 0; i_cnt < ss->n_instances; i_cnt++)
542 {
543 i = ss->instances[i_cnt];
544 if (NULL != i->proc)
545 stop_shared_service_instance (i);
546 cleanup_shared_service_instance (i);
547 }
548 GNUNET_free (ss->instances);
549 GNUNET_CONFIGURATION_destroy (ss->cfg);
550 GNUNET_free (ss->sname);
551 GNUNET_free (ss);
552 }
553 GNUNET_free (system->shared_services);
554 if (GNUNET_YES == remove_paths)
555 GNUNET_DISK_directory_remove (system->tmppath);
556 GNUNET_free (system->tmppath);
557 GNUNET_free (system->trusted_ip);
558 GNUNET_free (system->hostname);
559 GNUNET_free (system);
560}
561
562
563/**
564 * Reserve a TCP or UDP port for a peer.
565 *
566 * @param system system to use for reservation tracking
567 * @return 0 if no free port was available
568 */
569uint16_t
570GNUNET_TESTING_reserve_port (struct GNUNET_TESTING_System *system)
571{
572 struct GNUNET_NETWORK_Handle *socket;
573 struct addrinfo hint;
574 struct addrinfo *ret;
575 struct addrinfo *ai;
576 uint32_t *port_buckets;
577 char *open_port_str;
578 int bind_status;
579 uint32_t xor_image;
580 uint16_t index;
581 uint16_t open_port;
582 uint16_t pos;
583
584 /*
585 FIXME: Instead of using getaddrinfo we should try to determine the port
586 status by the following heurestics.
587
588 On systems which support both IPv4 and IPv6, only ports open on both
589 address families are considered open.
590 On system with either IPv4 or IPv6. A port is considered open if it's
591 open in the respective address family
592 */hint.ai_family = AF_UNSPEC; /* IPv4 and IPv6 */
593 hint.ai_socktype = 0;
594 hint.ai_protocol = 0;
595 hint.ai_addrlen = 0;
596 hint.ai_addr = NULL;
597 hint.ai_canonname = NULL;
598 hint.ai_next = NULL;
599 hint.ai_flags = AI_PASSIVE | AI_NUMERICSERV; /* Wild card address */
600 port_buckets = system->reserved_ports;
601 for (index = (system->lowport / 32) + 1; index < (system->highport / 32);
602 index++)
603 {
604 xor_image = (UINT32_MAX ^ port_buckets[index]);
605 if (0 == xor_image) /* Ports in the bucket are full */
606 continue;
607 pos = system->lowport % 32;
608 while (pos < 32)
609 {
610 if (0 == ((xor_image >> pos) & 1U))
611 {
612 pos++;
613 continue;
614 }
615 open_port = (index * 32) + pos;
616 if (open_port >= system->highport)
617 return 0;
618 GNUNET_asprintf (&open_port_str, "%u", (unsigned int) open_port);
619 ret = NULL;
620 GNUNET_assert (0 == getaddrinfo (NULL, open_port_str, &hint, &ret));
621 GNUNET_free (open_port_str);
622 bind_status = GNUNET_NO;
623 for (ai = ret; NULL != ai; ai = ai->ai_next)
624 {
625 socket = GNUNET_NETWORK_socket_create (ai->ai_family, SOCK_STREAM, 0);
626 if (NULL == socket)
627 continue;
628 bind_status =
629 GNUNET_NETWORK_socket_bind (socket, ai->ai_addr, ai->ai_addrlen);
630 GNUNET_NETWORK_socket_close (socket);
631 if (GNUNET_OK != bind_status)
632 break;
633 socket = GNUNET_NETWORK_socket_create (ai->ai_family, SOCK_DGRAM, 0);
634 if (NULL == socket)
635 continue;
636 bind_status =
637 GNUNET_NETWORK_socket_bind (socket, ai->ai_addr, ai->ai_addrlen);
638 GNUNET_NETWORK_socket_close (socket);
639 if (GNUNET_OK != bind_status)
640 break;
641 }
642 port_buckets[index] |= (1U << pos); /* Set the port bit */
643 freeaddrinfo (ret);
644 if (GNUNET_OK == bind_status)
645 {
646 LOG (GNUNET_ERROR_TYPE_DEBUG,
647 "Found a free port %u\n",
648 (unsigned int) open_port);
649 return open_port;
650 }
651 pos++;
652 }
653 }
654 return 0;
655}
656
657
658/**
659 * Release reservation of a TCP or UDP port for a peer
660 * (used during #GNUNET_TESTING_peer_destroy()).
661 *
662 * @param system system to use for reservation tracking
663 * @param port reserved port to release
664 */
665void
666GNUNET_TESTING_release_port (struct GNUNET_TESTING_System *system,
667 uint16_t port)
668{
669 uint32_t *port_buckets;
670 uint16_t bucket;
671 uint16_t pos;
672
673 port_buckets = system->reserved_ports;
674 bucket = port / 32;
675 pos = port % 32;
676 LOG (GNUNET_ERROR_TYPE_DEBUG, "Releasing port %u\n", port);
677 if (0 == (port_buckets[bucket] & (1U << pos)))
678 {
679 GNUNET_break (0); /* Port was not reserved by us using reserve_port() */
680 return;
681 }
682 port_buckets[bucket] &= ~(1U << pos);
683}
684
685
686/**
687 * Testing includes a number of pre-created hostkeys for
688 * faster peer startup. This function can be used to
689 * access the n-th key of those pre-created hostkeys; note
690 * that these keys are ONLY useful for testing and not
691 * secure as the private keys are part of the public
692 * GNUnet source code.
693 *
694 * This is primarily a helper function used internally
695 * by #GNUNET_TESTING_peer_configure.
696 *
697 * @param system the testing system handle
698 * @param key_number desired pre-created hostkey to obtain
699 * @param id set to the peer's identity (hash of the public
700 * key; if NULL, NULL is returned immediately
701 * @return NULL on error (not enough keys)
702 */
703struct GNUNET_CRYPTO_EddsaPrivateKey *
704GNUNET_TESTING_hostkey_get (const struct GNUNET_TESTING_System *system,
705 uint32_t key_number,
706 struct GNUNET_PeerIdentity *id)
707{
708 struct GNUNET_CRYPTO_EddsaPrivateKey *private_key;
709
710 if ((NULL == id) || (NULL == system->hostkeys_data))
711 return NULL;
712 if (key_number >= system->total_hostkeys)
713 {
714 LOG (GNUNET_ERROR_TYPE_ERROR,
715 _ ("Key number %u does not exist\n"),
716 key_number);
717 return NULL;
718 }
719 private_key = GNUNET_new (struct GNUNET_CRYPTO_EddsaPrivateKey);
720 GNUNET_memcpy (private_key,
721 system->hostkeys_data
722 + (key_number * GNUNET_TESTING_HOSTKEYFILESIZE),
723 GNUNET_TESTING_HOSTKEYFILESIZE);
724 GNUNET_CRYPTO_eddsa_key_get_public (private_key, &id->public_key);
725 return private_key;
726}
727
728
729/**
730 * Structure for holding data to build new configurations from a configuration
731 * template
732 */
733struct UpdateContext
734{
735 /**
736 * The system for which we are building configurations
737 */
738 struct GNUNET_TESTING_System *system;
739
740 /**
741 * The configuration we are building
742 */
743 struct GNUNET_CONFIGURATION_Handle *cfg;
744
745 /**
746 * The customized service home path for this peer
747 */
748 char *gnunet_home;
749
750 /**
751 * Array of ports currently allocated to this peer. These ports will be
752 * released upon peer destroy and can be used by other peers which are
753 * configured after.
754 */
755 uint16_t *ports;
756
757 /**
758 * The number of ports in the above array
759 */
760 unsigned int nports;
761
762 /**
763 * build status - to signal error while building a configuration
764 */
765 int status;
766};
767
768
769/**
770 * Function to iterate over options. Copies
771 * the options to the target configuration,
772 * updating PORT values as needed.
773 *
774 * @param cls the UpdateContext
775 * @param section name of the section
776 * @param option name of the option
777 * @param value value of the option
778 */
779static void
780update_config (void *cls,
781 const char *section,
782 const char *option,
783 const char *value)
784{
785 struct UpdateContext *uc = cls;
786 unsigned int ival;
787 char cval[12];
788 char uval[PATH_MAX];
789 char *single_variable;
790 char *per_host_variable;
791 unsigned long long num_per_host;
792 uint16_t new_port;
793
794 if (GNUNET_OK != uc->status)
795 return;
796 if (! ((0 == strcmp (option, "PORT")) || (0 == strcmp (option, "UNIXPATH")) ||
797 (0 == strcmp (option, "HOSTNAME"))))
798 return;
799 GNUNET_asprintf (&single_variable, "single_%s_per_host", section);
800 GNUNET_asprintf (&per_host_variable, "num_%s_per_host", section);
801 if ((0 == strcmp (option, "PORT")) && (1 == sscanf (value, "%u", &ival)))
802 {
803 if ((ival != 0) &&
804 (GNUNET_YES != GNUNET_CONFIGURATION_get_value_yesno (uc->cfg,
805 "testing",
806 single_variable)))
807 {
808 new_port = GNUNET_TESTING_reserve_port (uc->system);
809 if (0 == new_port)
810 {
811 uc->status = GNUNET_SYSERR;
812 GNUNET_free (single_variable);
813 GNUNET_free (per_host_variable);
814 return;
815 }
816 GNUNET_snprintf (cval, sizeof(cval), "%u", new_port);
817 value = cval;
818 GNUNET_array_append (uc->ports, uc->nports, new_port);
819 }
820 else if ((ival != 0) &&
821 (GNUNET_YES ==
822 GNUNET_CONFIGURATION_get_value_yesno (uc->cfg,
823 "testing",
824 single_variable)) &&
825 GNUNET_CONFIGURATION_get_value_number (uc->cfg,
826 "testing",
827 per_host_variable,
828 &num_per_host))
829 {
830 /* GNUNET_snprintf (cval, sizeof (cval), "%u", */
831 /* ival + ctx->fdnum % num_per_host); */
832 /* value = cval; */
833 GNUNET_break (0); /* FIXME */
834 }
835 }
836 if (0 == strcmp (option, "UNIXPATH"))
837 {
838 if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_yesno (uc->cfg,
839 "testing",
840 single_variable))
841 {
842 GNUNET_snprintf (uval,
843 sizeof(uval),
844 "%s/%s.sock",
845 uc->gnunet_home,
846 section);
847 value = uval;
848 }
849 else if ((GNUNET_YES ==
850 GNUNET_CONFIGURATION_get_value_number (uc->cfg,
851 "testing",
852 per_host_variable,
853 &num_per_host)) &&
854 (num_per_host > 0))
855 {
856 GNUNET_break (0); /* FIXME */
857 }
858 }
859 if (0 == strcmp (option, "HOSTNAME"))
860 {
861 value = (NULL == uc->system->hostname) ? "localhost" : uc->system->hostname;
862 }
863 GNUNET_free (single_variable);
864 GNUNET_free (per_host_variable);
865 GNUNET_CONFIGURATION_set_value_string (uc->cfg, section, option, value);
866}
867
868
869/**
870 * Section iterator to set ACCEPT_FROM/ACCEPT_FROM6 to include the address of
871 * 'trusted_hosts' in all sections
872 *
873 * @param cls the UpdateContext
874 * @param section name of the section
875 */
876static void
877update_config_sections (void *cls, const char *section)
878{
879 struct UpdateContext *uc = cls;
880 char **ikeys;
881 char *val;
882 char *ptr;
883 char *orig_allowed_hosts;
884 char *allowed_hosts;
885 char *ACCEPT_FROM_key;
886 uint16_t ikeys_cnt;
887 uint16_t key;
888
889 ikeys_cnt = 0;
890 val = NULL;
891 /* Ignore certain options from sections. See
892 https://gnunet.org/bugs/view.php?id=2476 */
893 if (GNUNET_YES ==
894 GNUNET_CONFIGURATION_have_value (uc->cfg, section, "TESTING_IGNORE_KEYS"))
895 {
896 GNUNET_assert (GNUNET_YES ==
897 GNUNET_CONFIGURATION_get_value_string (uc->cfg,
898 section,
899 "TESTING_IGNORE_KEYS",
900 &val));
901 ptr = val;
902 for (ikeys_cnt = 0; NULL != (ptr = strstr (ptr, ";")); ikeys_cnt++)
903 ptr++;
904 if (0 == ikeys_cnt)
905 GNUNET_break (0);
906 else
907 {
908 ikeys = GNUNET_malloc ((sizeof(char *)) * ikeys_cnt);
909 ptr = val;
910 for (key = 0; key < ikeys_cnt; key++)
911 {
912 ikeys[key] = ptr;
913 ptr = strstr (ptr, ";");
914 GNUNET_assert (NULL != ptr); /* worked just before... */
915 *ptr = '\0';
916 ptr++;
917 }
918 }
919 }
920 if (0 != ikeys_cnt)
921 {
922 for (key = 0; key < ikeys_cnt; key++)
923 {
924 if (NULL != strstr (ikeys[key], "ADVERTISED_PORT"))
925 break;
926 }
927 if ((key == ikeys_cnt) &&
928 (GNUNET_YES ==
929 GNUNET_CONFIGURATION_have_value (uc->cfg, section, "ADVERTISED_PORT")))
930 {
931 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (uc->cfg,
932 section,
933 "PORT",
934 &ptr))
935 {
936 GNUNET_CONFIGURATION_set_value_string (uc->cfg,
937 section,
938 "ADVERTISED_PORT",
939 ptr);
940 GNUNET_free (ptr);
941 }
942 }
943 for (key = 0; key < ikeys_cnt; key++)
944 {
945 if (NULL != strstr (ikeys[key], "ACCEPT_FROM"))
946 {
947 GNUNET_free (ikeys);
948 GNUNET_free (val);
949 return;
950 }
951 }
952 GNUNET_free (ikeys);
953 }
954 GNUNET_free (val);
955 ACCEPT_FROM_key = "ACCEPT_FROM";
956 if ((NULL != uc->system->trusted_ip) &&
957 (NULL != strstr (uc->system->trusted_ip, ":"))) /* IPv6 in use */
958 ACCEPT_FROM_key = "ACCEPT_FROM6";
959 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (uc->cfg,
960 section,
961 ACCEPT_FROM_key,
962 &orig_allowed_hosts))
963 {
964 orig_allowed_hosts = GNUNET_strdup ("127.0.0.1;");
965 }
966 if (NULL == uc->system->trusted_ip)
967 allowed_hosts = GNUNET_strdup (orig_allowed_hosts);
968 else
969 GNUNET_asprintf (&allowed_hosts,
970 "%s%s;",
971 orig_allowed_hosts,
972 uc->system->trusted_ip);
973 GNUNET_free (orig_allowed_hosts);
974 GNUNET_CONFIGURATION_set_value_string (uc->cfg,
975 section,
976 ACCEPT_FROM_key,
977 allowed_hosts);
978 GNUNET_free (allowed_hosts);
979}
980
981
982static struct SharedServiceInstance *
983associate_shared_service (struct GNUNET_TESTING_System *system,
984 struct SharedService *ss,
985 struct GNUNET_CONFIGURATION_Handle *cfg)
986{
987 struct SharedServiceInstance *i;
988 struct GNUNET_CONFIGURATION_Handle *temp;
989 char *gnunet_home;
990 uint32_t port;
991
992 ss->n_peers++;
993 if (((0 == ss->share) && (NULL == ss->instances)) ||
994 ((0 != ss->share) &&
995 (ss->n_instances < ((ss->n_peers + ss->share - 1) / ss->share))))
996 {
997 i = GNUNET_new (struct SharedServiceInstance);
998 i->ss = ss;
999 (void) GNUNET_asprintf (&gnunet_home,
1000 "%s/shared/%s/%u",
1001 system->tmppath,
1002 ss->sname,
1003 ss->n_instances);
1004 (void) GNUNET_asprintf (&i->unix_sock, "%s/sock", gnunet_home);
1005 port = GNUNET_TESTING_reserve_port (system);
1006 if (0 == port)
1007 {
1008 GNUNET_free (gnunet_home);
1009 cleanup_shared_service_instance (i);
1010 return NULL;
1011 }
1012 GNUNET_array_append (ss->instances, ss->n_instances, i);
1013 temp = GNUNET_CONFIGURATION_dup (ss->cfg);
1014 (void) GNUNET_asprintf (&i->port_str, "%u", port);
1015 (void) GNUNET_asprintf (&i->cfg_fn, "%s/config", gnunet_home);
1016 GNUNET_CONFIGURATION_set_value_string (temp,
1017 "PATHS",
1018 "GNUNET_HOME",
1019 gnunet_home);
1020 GNUNET_free (gnunet_home);
1021 GNUNET_CONFIGURATION_set_value_string (temp,
1022 ss->sname,
1023 "UNIXPATH",
1024 i->unix_sock);
1025 GNUNET_CONFIGURATION_set_value_string (temp,
1026 ss->sname,
1027 "PORT",
1028 i->port_str);
1029 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_write (temp, i->cfg_fn))
1030 {
1031 GNUNET_CONFIGURATION_destroy (temp);
1032 cleanup_shared_service_instance (i);
1033 return NULL;
1034 }
1035 GNUNET_CONFIGURATION_destroy (temp);
1036 }
1037 else
1038 {
1039 GNUNET_assert (NULL != ss->instances);
1040 GNUNET_assert (0 < ss->n_instances);
1041 i = ss->instances[ss->n_instances - 1];
1042 }
1043 GNUNET_CONFIGURATION_iterate_section_values (ss->cfg,
1044 ss->sname,
1045 &cfg_copy_iterator,
1046 cfg);
1047 GNUNET_CONFIGURATION_set_value_string (cfg,
1048 ss->sname,
1049 "UNIXPATH",
1050 i->unix_sock);
1051 GNUNET_CONFIGURATION_set_value_string (cfg, ss->sname, "PORT", i->port_str);
1052 return i;
1053}
1054
1055
1056/**
1057 * Create a new configuration using the given configuration as a template;
1058 * ports and paths will be modified to select available ports on the local
1059 * system. The default configuration will be available in PATHS section under
1060 * the option DEFAULTCONFIG after the call. GNUNET_HOME is also set in PATHS
1061 * section to the temporary directory specific to this configuration. If we run
1062 * out of "*port" numbers, return #GNUNET_SYSERR.
1063 *
1064 * This is primarily a helper function used internally
1065 * by 'GNUNET_TESTING_peer_configure'.
1066 *
1067 * @param system system to use to coordinate resource usage
1068 * @param cfg template configuration to update
1069 * @param ports array with port numbers used in the created configuration.
1070 * Will be updated upon successful return. Can be NULL
1071 * @param nports the size of the `ports' array. Will be updated.
1072 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error - the configuration will
1073 * be incomplete and should not be used there upon
1074 */
1075static int
1076GNUNET_TESTING_configuration_create_ (struct GNUNET_TESTING_System *system,
1077 struct GNUNET_CONFIGURATION_Handle *cfg,
1078 uint16_t **ports,
1079 unsigned int *nports)
1080{
1081 struct UpdateContext uc;
1082 char *default_config;
1083
1084 uc.system = system;
1085 uc.cfg = cfg;
1086 uc.status = GNUNET_OK;
1087 uc.ports = NULL;
1088 uc.nports = 0;
1089 GNUNET_asprintf (&uc.gnunet_home,
1090 "%s/%u",
1091 system->tmppath,
1092 system->path_counter++);
1093 GNUNET_asprintf (&default_config, "%s/config", uc.gnunet_home);
1094 GNUNET_CONFIGURATION_set_value_string (cfg,
1095 "PATHS",
1096 "DEFAULTCONFIG",
1097 default_config);
1098 GNUNET_CONFIGURATION_set_value_string (cfg, "arm", "CONFIG", default_config);
1099 GNUNET_free (default_config);
1100 GNUNET_CONFIGURATION_set_value_string (cfg,
1101 "PATHS",
1102 "GNUNET_HOME",
1103 uc.gnunet_home);
1104 /* make PORTs and UNIXPATHs unique */
1105 GNUNET_CONFIGURATION_iterate (cfg, &update_config, &uc);
1106 /* allow connections to services from system trusted_ip host */
1107 GNUNET_CONFIGURATION_iterate_sections (cfg, &update_config_sections, &uc);
1108 /* enable loopback-based connections between peers */
1109 GNUNET_CONFIGURATION_set_value_string (cfg, "nat", "USE_LOCALADDR", "YES");
1110 GNUNET_free (uc.gnunet_home);
1111 if ((NULL != ports) && (NULL != nports))
1112 {
1113 *ports = uc.ports;
1114 *nports = uc.nports;
1115 }
1116 else
1117 GNUNET_free (uc.ports);
1118 return uc.status;
1119}
1120
1121
1122/**
1123 * Create a new configuration using the given configuration as a template;
1124 * ports and paths will be modified to select available ports on the local
1125 * system. The default configuration will be available in PATHS section under
1126 * the option DEFAULTCONFIG after the call. GNUNET_HOME is also set in PATHS
1127 * section to the temporary directory specific to this configuration. If we run
1128 * out of "*port" numbers, return #GNUNET_SYSERR.
1129 *
1130 * This is primarily a helper function used internally
1131 * by #GNUNET_TESTING_peer_configure().
1132 *
1133 * @param system system to use to coordinate resource usage
1134 * @param cfg template configuration to update
1135 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error - the configuration will
1136 * be incomplete and should not be used there upon
1137 */
1138int
1139GNUNET_TESTING_configuration_create (struct GNUNET_TESTING_System *system,
1140 struct GNUNET_CONFIGURATION_Handle *cfg)
1141{
1142 return GNUNET_TESTING_configuration_create_ (system, cfg, NULL, NULL);
1143}
1144
1145
1146/**
1147 * Configure a GNUnet peer. GNUnet must be installed on the local
1148 * system and available in the PATH.
1149 *
1150 * @param system system to use to coordinate resource usage
1151 * @param cfg configuration to use; will be UPDATED (to reflect needed
1152 * changes in port numbers and paths)
1153 * @param key_number number of the hostkey to use for the peer
1154 * @param id identifier for the daemon, will be set, can be NULL
1155 * @param emsg set to freshly allocated error message (set to NULL on success),
1156 * can be NULL
1157 * @return handle to the peer, NULL on error
1158 */
1159struct GNUNET_TESTING_Peer *
1160GNUNET_TESTING_peer_configure (struct GNUNET_TESTING_System *system,
1161 struct GNUNET_CONFIGURATION_Handle *cfg,
1162 uint32_t key_number,
1163 struct GNUNET_PeerIdentity *id,
1164 char **emsg)
1165{
1166 struct GNUNET_TESTING_Peer *peer;
1167 struct GNUNET_DISK_FileHandle *fd;
1168 char *hostkey_filename;
1169 char *config_filename;
1170 char *libexec_binary;
1171 char *emsg_;
1172 struct GNUNET_CRYPTO_EddsaPrivateKey *pk;
1173 uint16_t *ports;
1174 struct SharedService *ss;
1175 struct SharedServiceInstance **ss_instances;
1176 unsigned int cnt;
1177 unsigned int nports;
1178
1179 ports = NULL;
1180 nports = 0;
1181 ss_instances = NULL;
1182 if (NULL != emsg)
1183 *emsg = NULL;
1184 if (key_number >= system->total_hostkeys)
1185 {
1186 GNUNET_asprintf (
1187 &emsg_,
1188 _ (
1189 "You attempted to create a testbed with more than %u hosts. Please precompute more hostkeys first.\n"),
1190 (unsigned int) system->total_hostkeys);
1191 goto err_ret;
1192 }
1193 pk = NULL;
1194 if ((NULL != id) &&
1195 (NULL == (pk = GNUNET_TESTING_hostkey_get (system, key_number, id))))
1196 {
1197 GNUNET_asprintf (&emsg_,
1198 _ ("Failed to initialize hostkey for peer %u\n"),
1199 (unsigned int) key_number);
1200 goto err_ret;
1201 }
1202 if (NULL != pk)
1203 GNUNET_free (pk);
1204 if (GNUNET_NO == GNUNET_CONFIGURATION_have_value (cfg, "PEER", "PRIVATE_KEY"))
1205 {
1206 GNUNET_asprintf (
1207 &emsg_,
1208 _ ("PRIVATE_KEY option in PEER section missing in configuration\n"));
1209 goto err_ret;
1210 }
1211 /* Remove sections for shared services */
1212 for (cnt = 0; cnt < system->n_shared_services; cnt++)
1213 {
1214 ss = system->shared_services[cnt];
1215 GNUNET_CONFIGURATION_remove_section (cfg, ss->sname);
1216 }
1217 if (GNUNET_OK !=
1218 GNUNET_TESTING_configuration_create_ (system, cfg, &ports, &nports))
1219 {
1220 GNUNET_asprintf (&emsg_,
1221 _ ("Failed to create configuration for peer "
1222 "(not enough free ports?)\n"));
1223 goto err_ret;
1224 }
1225 GNUNET_assert (GNUNET_OK ==
1226 GNUNET_CONFIGURATION_get_value_filename (cfg,
1227 "PEER",
1228 "PRIVATE_KEY",
1229 &hostkey_filename));
1230 fd = GNUNET_DISK_file_open (hostkey_filename,
1231 GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_WRITE,
1232 GNUNET_DISK_PERM_USER_READ
1233 | GNUNET_DISK_PERM_USER_WRITE);
1234 if (NULL == fd)
1235 {
1236 GNUNET_asprintf (&emsg_,
1237 _ ("Cannot open hostkey file `%s': %s\n"),
1238 hostkey_filename,
1239 strerror (errno));
1240 GNUNET_free (hostkey_filename);
1241 goto err_ret;
1242 }
1243 GNUNET_free (hostkey_filename);
1244 if (GNUNET_TESTING_HOSTKEYFILESIZE !=
1245 GNUNET_DISK_file_write (fd,
1246 system->hostkeys_data
1247 + (key_number * GNUNET_TESTING_HOSTKEYFILESIZE),
1248 GNUNET_TESTING_HOSTKEYFILESIZE))
1249 {
1250 GNUNET_asprintf (&emsg_,
1251 _ ("Failed to write hostkey file for peer %u: %s\n"),
1252 (unsigned int) key_number,
1253 strerror (errno));
1254 GNUNET_DISK_file_close (fd);
1255 goto err_ret;
1256 }
1257 GNUNET_DISK_file_close (fd);
1258 ss_instances = GNUNET_malloc (sizeof(struct SharedServiceInstance *)
1259 * system->n_shared_services);
1260 for (cnt = 0; cnt < system->n_shared_services; cnt++)
1261 {
1262 ss = system->shared_services[cnt];
1263 ss_instances[cnt] = associate_shared_service (system, ss, cfg);
1264 if (NULL == ss_instances[cnt])
1265 {
1266 emsg_ = GNUNET_strdup ("FIXME");
1267 goto err_ret;
1268 }
1269 }
1270 GNUNET_assert (GNUNET_OK ==
1271 GNUNET_CONFIGURATION_get_value_filename (cfg,
1272 "PATHS",
1273 "DEFAULTCONFIG",
1274 &config_filename));
1275 if (GNUNET_OK != GNUNET_CONFIGURATION_write (cfg, config_filename))
1276 {
1277 GNUNET_asprintf (&emsg_,
1278 _ (
1279 "Failed to write configuration file `%s' for peer %u: %s\n"),
1280 config_filename,
1281 (unsigned int) key_number,
1282 strerror (errno));
1283 GNUNET_free (config_filename);
1284 goto err_ret;
1285 }
1286 peer = GNUNET_new (struct GNUNET_TESTING_Peer);
1287 peer->ss_instances = ss_instances;
1288 peer->cfgfile = config_filename; /* Free in peer_destroy */
1289 peer->cfg = GNUNET_CONFIGURATION_dup (cfg);
1290 libexec_binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-arm");
1291 if (GNUNET_SYSERR ==
1292 GNUNET_CONFIGURATION_get_value_string (cfg,
1293 "arm",
1294 "PREFIX",
1295 &peer->main_binary))
1296 {
1297 /* No prefix */
1298 GNUNET_asprintf (&peer->main_binary, "%s", libexec_binary);
1299 peer->args = GNUNET_strdup ("");
1300 }
1301 else
1302 {
1303 peer->args = GNUNET_strdup (libexec_binary);
1304 }
1305 peer->system = system;
1306 peer->key_number = key_number;
1307 GNUNET_free (libexec_binary);
1308 peer->ports = ports; /* Free in peer_destroy */
1309 peer->nports = nports;
1310 return peer;
1311
1312 err_ret:
1313 GNUNET_free (ss_instances);
1314 GNUNET_free (ports);
1315 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s", emsg_);
1316 if (NULL != emsg)
1317 *emsg = emsg_;
1318 else
1319 GNUNET_free (emsg_);
1320 return NULL;
1321}
1322
1323
1324/**
1325 * Obtain the peer identity from a peer handle.
1326 *
1327 * @param peer peer handle for which we want the peer's identity
1328 * @param id identifier for the daemon, will be set
1329 */
1330void
1331GNUNET_TESTING_peer_get_identity (struct GNUNET_TESTING_Peer *peer,
1332 struct GNUNET_PeerIdentity *id)
1333{
1334 if (NULL != peer->id)
1335 {
1336 GNUNET_memcpy (id, peer->id, sizeof(struct GNUNET_PeerIdentity));
1337 return;
1338 }
1339 peer->id = GNUNET_new (struct GNUNET_PeerIdentity);
1340 GNUNET_free_nz (
1341 GNUNET_TESTING_hostkey_get (peer->system, peer->key_number, peer->id));
1342 GNUNET_memcpy (id, peer->id, sizeof(struct GNUNET_PeerIdentity));
1343}
1344
1345
1346/**
1347 * Start the peer.
1348 *
1349 * @param peer peer to start
1350 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error (i.e. peer already running)
1351 */
1352int
1353GNUNET_TESTING_peer_start (struct GNUNET_TESTING_Peer *peer)
1354{
1355 struct SharedServiceInstance *i;
1356 unsigned int cnt;
1357
1358 if (NULL != peer->main_process)
1359 {
1360 GNUNET_break (0);
1361 return GNUNET_SYSERR;
1362 }
1363 GNUNET_assert (NULL != peer->cfgfile);
1364 for (cnt = 0; cnt < peer->system->n_shared_services; cnt++)
1365 {
1366 i = peer->ss_instances[cnt];
1367 if ((0 == i->n_refs) &&
1368 (GNUNET_SYSERR == start_shared_service_instance (i)))
1369 return GNUNET_SYSERR;
1370 i->n_refs++;
1371 }
1372 peer->main_binary =
1373 GNUNET_CONFIGURATION_expand_dollar (peer->cfg, peer->main_binary);
1374 peer->main_process =
1375 GNUNET_OS_start_process_s (GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
1376 NULL,
1377 peer->main_binary,
1378 peer->args,
1379 "-c",
1380 peer->cfgfile,
1381 NULL);
1382 if (NULL == peer->main_process)
1383 {
1384 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1385 _ ("Failed to start `%s': %s\n"),
1386 peer->main_binary,
1387 strerror (errno));
1388 return GNUNET_SYSERR;
1389 }
1390 return GNUNET_OK;
1391}
1392
1393
1394/**
1395 * Sends SIGTERM to the peer's main process
1396 *
1397 * @param peer the handle to the peer
1398 * @return #GNUNET_OK if successful; #GNUNET_SYSERR if the main process is NULL
1399 * or upon any error while sending SIGTERM
1400 */
1401int
1402GNUNET_TESTING_peer_kill (struct GNUNET_TESTING_Peer *peer)
1403{
1404 struct SharedServiceInstance *i;
1405 unsigned int cnt;
1406
1407 if (NULL == peer->main_process)
1408 {
1409 GNUNET_break (0);
1410 return GNUNET_SYSERR;
1411 }
1412 if (0 != GNUNET_OS_process_kill (peer->main_process, GNUNET_TERM_SIG))
1413 return GNUNET_SYSERR;
1414 for (cnt = 0; cnt < peer->system->n_shared_services; cnt++)
1415 {
1416 i = peer->ss_instances[cnt];
1417 GNUNET_assert (0 != i->n_refs);
1418 i->n_refs--;
1419 if (0 == i->n_refs)
1420 stop_shared_service_instance (i);
1421 }
1422 return GNUNET_OK;
1423}
1424
1425
1426/**
1427 * Waits for a peer to terminate. The peer's main process will also be destroyed.
1428 *
1429 * @param peer the handle to the peer
1430 * @return #GNUNET_OK if successful; #GNUNET_SYSERR if the main process is NULL
1431 * or upon any error while waiting
1432 */
1433int
1434GNUNET_TESTING_peer_wait (struct GNUNET_TESTING_Peer *peer)
1435{
1436 int ret;
1437
1438 if (NULL == peer->main_process)
1439 {
1440 GNUNET_break (0);
1441 return GNUNET_SYSERR;
1442 }
1443 ret = GNUNET_OS_process_wait (peer->main_process);
1444 GNUNET_OS_process_destroy (peer->main_process);
1445 peer->main_process = NULL;
1446 return ret;
1447}
1448
1449
1450/**
1451 * Stop the peer.
1452 *
1453 * @param peer peer to stop
1454 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
1455 */
1456int
1457GNUNET_TESTING_peer_stop (struct GNUNET_TESTING_Peer *peer)
1458{
1459 if (GNUNET_SYSERR == GNUNET_TESTING_peer_kill (peer))
1460 return GNUNET_SYSERR;
1461 if (GNUNET_SYSERR == GNUNET_TESTING_peer_wait (peer))
1462 return GNUNET_SYSERR;
1463 return GNUNET_OK;
1464}
1465
1466
1467/**
1468 * Function called whenever we connect to or disconnect from ARM.
1469 *
1470 * @param cls closure
1471 * @param connected #GNUNET_YES if connected, #GNUNET_NO if disconnected,
1472 * #GNUNET_SYSERR on error.
1473 */
1474static void
1475disconn_status (void *cls, int connected)
1476{
1477 struct GNUNET_TESTING_Peer *peer = cls;
1478
1479 if (GNUNET_SYSERR == connected)
1480 {
1481 peer->cb (peer->cb_cls, peer, connected);
1482 return;
1483 }
1484 if (GNUNET_YES == connected)
1485 {
1486 GNUNET_break (GNUNET_OK == GNUNET_TESTING_peer_kill (peer));
1487 return;
1488 }
1489 GNUNET_break (GNUNET_OK == GNUNET_TESTING_peer_wait (peer));
1490 GNUNET_ARM_disconnect (peer->ah);
1491 peer->ah = NULL;
1492 peer->cb (peer->cb_cls, peer, GNUNET_YES);
1493}
1494
1495
1496/**
1497 * Stop a peer asynchronously using ARM API. Peer's shutdown is signaled
1498 * through the GNUNET_TESTING_PeerStopCallback().
1499 *
1500 * @param peer the peer to stop
1501 * @param cb the callback to signal peer shutdown
1502 * @param cb_cls closure for the above callback
1503 * @return #GNUNET_OK upon successfully giving the request to the ARM API (this
1504 * does not mean that the peer is successfully stopped); #GNUNET_SYSERR
1505 * upon any error.
1506 */
1507int
1508GNUNET_TESTING_peer_stop_async (struct GNUNET_TESTING_Peer *peer,
1509 GNUNET_TESTING_PeerStopCallback cb,
1510 void *cb_cls)
1511{
1512 if (NULL == peer->main_process)
1513 return GNUNET_SYSERR;
1514 peer->ah = GNUNET_ARM_connect (peer->cfg, &disconn_status, peer);
1515 if (NULL == peer->ah)
1516 return GNUNET_SYSERR;
1517 peer->cb = cb;
1518 peer->cb_cls = cb_cls;
1519 return GNUNET_OK;
1520}
1521
1522
1523/**
1524 * Cancel a previous asynchronous peer stop request.
1525 * GNUNET_TESTING_peer_stop_async() should have been called before on the given
1526 * peer. It is an error to call this function if the peer stop callback was
1527 * already called
1528 *
1529 * @param peer the peer on which GNUNET_TESTING_peer_stop_async() was called
1530 * before.
1531 */
1532void
1533GNUNET_TESTING_peer_stop_async_cancel (struct GNUNET_TESTING_Peer *peer)
1534{
1535 GNUNET_assert (NULL != peer->ah);
1536 GNUNET_ARM_disconnect (peer->ah);
1537 peer->ah = NULL;
1538}
1539
1540
1541/**
1542 * Destroy the peer. Releases resources locked during peer configuration.
1543 * If the peer is still running, it will be stopped AND a warning will be
1544 * printed (users of the API should stop the peer explicitly first).
1545 *
1546 * @param peer peer to destroy
1547 */
1548void
1549GNUNET_TESTING_peer_destroy (struct GNUNET_TESTING_Peer *peer)
1550{
1551 unsigned int cnt;
1552
1553 if (NULL != peer->main_process)
1554 GNUNET_TESTING_peer_stop (peer);
1555 if (NULL != peer->ah)
1556 GNUNET_ARM_disconnect (peer->ah);
1557 GNUNET_free (peer->cfgfile);
1558 if (NULL != peer->cfg)
1559 GNUNET_CONFIGURATION_destroy (peer->cfg);
1560 GNUNET_free (peer->main_binary);
1561 GNUNET_free (peer->args);
1562 GNUNET_free (peer->id);
1563 GNUNET_free (peer->ss_instances);
1564 if (NULL != peer->ports)
1565 {
1566 for (cnt = 0; cnt < peer->nports; cnt++)
1567 GNUNET_TESTING_release_port (peer->system, peer->ports[cnt]);
1568 GNUNET_free (peer->ports);
1569 }
1570 GNUNET_free (peer);
1571}
1572
1573
1574/**
1575 * Start a single peer and run a test using the testing library.
1576 * Starts a peer using the given configuration and then invokes the
1577 * given callback. This function ALSO initializes the scheduler loop
1578 * and should thus be called directly from "main". The testcase
1579 * should self-terminate by invoking #GNUNET_SCHEDULER_shutdown().
1580 *
1581 * @param testdir only the directory name without any path. This is used for
1582 * all service homes; the directory will be created in a temporary
1583 * location depending on the underlying OS
1584 * @param cfgfilename name of the configuration file to use;
1585 * use NULL to only run with defaults
1586 * @param tm main function of the testcase
1587 * @param tm_cls closure for @a tm
1588 * @return 0 on success, 1 on error
1589 */
1590int
1591GNUNET_TESTING_peer_run (const char *testdir,
1592 const char *cfgfilename,
1593 GNUNET_TESTING_TestMain tm,
1594 void *tm_cls)
1595{
1596 return GNUNET_TESTING_service_run (testdir, "arm", cfgfilename, tm, tm_cls);
1597}
1598
1599
1600/**
1601 * Structure for holding service data
1602 */
1603struct ServiceContext
1604{
1605 /**
1606 * The configuration of the peer in which the service is run
1607 */
1608 const struct GNUNET_CONFIGURATION_Handle *cfg;
1609
1610 /**
1611 * Callback to signal service startup
1612 */
1613 GNUNET_TESTING_TestMain tm;
1614
1615 /**
1616 * The peer in which the service is run.
1617 */
1618 struct GNUNET_TESTING_Peer *peer;
1619
1620 /**
1621 * Closure for the above callback
1622 */
1623 void *tm_cls;
1624};
1625
1626
1627/**
1628 * Callback to be called when SCHEDULER has been started
1629 *
1630 * @param cls the ServiceContext
1631 */
1632static void
1633service_run_main (void *cls)
1634{
1635 struct ServiceContext *sc = cls;
1636
1637 sc->tm (sc->tm_cls, sc->cfg, sc->peer);
1638}
1639
1640
1641/**
1642 * Start a single service (no ARM, except of course if the given
1643 * service name is 'arm') and run a test using the testing library.
1644 * Starts a service using the given configuration and then invokes the
1645 * given callback. This function ALSO initializes the scheduler loop
1646 * and should thus be called directly from "main". The testcase
1647 * should self-terminate by invoking #GNUNET_SCHEDULER_shutdown().
1648 *
1649 * This function is useful if the testcase is for a single service
1650 * and if that service doesn't itself depend on other services.
1651 *
1652 * @param testdir only the directory name without any path. This is used for
1653 * all service homes; the directory will be created in a temporary
1654 * location depending on the underlying OS
1655 * @param service_name name of the service to run
1656 * @param cfgfilename name of the configuration file to use;
1657 * use NULL to only run with defaults
1658 * @param tm main function of the testcase
1659 * @param tm_cls closure for @a tm
1660 * @return 0 on success, 1 on error
1661 */
1662int
1663GNUNET_TESTING_service_run (const char *testdir,
1664 const char *service_name,
1665 const char *cfgfilename,
1666 GNUNET_TESTING_TestMain tm,
1667 void *tm_cls)
1668{
1669 struct ServiceContext sc;
1670 struct GNUNET_TESTING_System *system;
1671 struct GNUNET_TESTING_Peer *peer;
1672 struct GNUNET_CONFIGURATION_Handle *cfg;
1673 char *binary;
1674 char *libexec_binary;
1675
1676 GNUNET_log_setup (testdir, "WARNING", NULL);
1677 system = GNUNET_TESTING_system_create (testdir, "127.0.0.1", NULL, NULL);
1678 if (NULL == system)
1679 return 1;
1680 cfg = GNUNET_CONFIGURATION_create ();
1681 if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg, cfgfilename))
1682 {
1683 LOG (GNUNET_ERROR_TYPE_ERROR,
1684 _ ("Failed to load configuration from %s\n"),
1685 cfgfilename);
1686 GNUNET_CONFIGURATION_destroy (cfg);
1687 GNUNET_TESTING_system_destroy (system, GNUNET_YES);
1688 return 1;
1689 }
1690 peer = GNUNET_TESTING_peer_configure (system, cfg, 0, NULL, NULL);
1691 if (NULL == peer)
1692 {
1693 GNUNET_CONFIGURATION_destroy (cfg);
1694 hostkeys_unload (system);
1695 GNUNET_TESTING_system_destroy (system, GNUNET_YES);
1696 return 1;
1697 }
1698 GNUNET_free (peer->main_binary);
1699 GNUNET_free (peer->args);
1700 GNUNET_asprintf (&binary, "gnunet-service-%s", service_name);
1701 libexec_binary = GNUNET_OS_get_libexec_binary_path (binary);
1702 if (GNUNET_SYSERR ==
1703 GNUNET_CONFIGURATION_get_value_string (cfg,
1704 service_name,
1705 "PREFIX",
1706 &peer->main_binary))
1707 {
1708 /* No prefix */
1709 GNUNET_asprintf (&peer->main_binary, "%s", libexec_binary);
1710 peer->args = GNUNET_strdup ("");
1711 }
1712 else
1713 peer->args = GNUNET_strdup (libexec_binary);
1714
1715 GNUNET_free (libexec_binary);
1716 GNUNET_free (binary);
1717 if (GNUNET_OK != GNUNET_TESTING_peer_start (peer))
1718 {
1719 GNUNET_TESTING_peer_destroy (peer);
1720 GNUNET_CONFIGURATION_destroy (cfg);
1721 GNUNET_TESTING_system_destroy (system, GNUNET_YES);
1722 return 1;
1723 }
1724 sc.cfg = cfg;
1725 sc.tm = tm;
1726 sc.tm_cls = tm_cls;
1727 sc.peer = peer;
1728 GNUNET_SCHEDULER_run (&service_run_main, &sc); /* Scheduler loop */
1729 if ((NULL != peer->main_process) &&
1730 (GNUNET_OK != GNUNET_TESTING_peer_stop (peer)))
1731 {
1732 GNUNET_TESTING_peer_destroy (peer);
1733 GNUNET_CONFIGURATION_destroy (cfg);
1734 GNUNET_TESTING_system_destroy (system, GNUNET_YES);
1735 return 1;
1736 }
1737 GNUNET_TESTING_peer_destroy (peer);
1738 GNUNET_CONFIGURATION_destroy (cfg);
1739 GNUNET_TESTING_system_destroy (system, GNUNET_YES);
1740 return 0;
1741}
1742
1743
1744/**
1745 * Sometimes we use the binary name to determine which specific
1746 * test to run. In those cases, the string after the last "_"
1747 * in 'argv[0]' specifies a string that determines the configuration
1748 * file or plugin to use.
1749 *
1750 * This function returns the respective substring, taking care
1751 * of issues such as binaries ending in '.exe' on W32.
1752 *
1753 * @param argv0 the name of the binary
1754 * @return string between the last '_' and the '.exe' (or the end of the string),
1755 * NULL if argv0 has no '_'
1756 */
1757char *
1758GNUNET_TESTING_get_testname_from_underscore (const char *argv0)
1759{
1760 size_t slen = strlen (argv0) + 1;
1761 char sbuf[slen];
1762 char *ret;
1763 char *dot;
1764
1765 GNUNET_memcpy (sbuf, argv0, slen);
1766 ret = strrchr (sbuf, '_');
1767 if (NULL == ret)
1768 return NULL;
1769 ret++; /* skip underscore */
1770 dot = strchr (ret, '.');
1771 if (NULL != dot)
1772 *dot = '\0';
1773 return GNUNET_strdup (ret);
1774}
1775
1776
1777static unsigned int
1778get_first_value (char *line)
1779{
1780 char *copy;
1781 size_t slen;
1782 char *token;
1783 unsigned int ret;
1784 char *rest = NULL;
1785
1786 slen = strlen (line) + 1;
1787 copy = malloc (slen);
1788 memcpy (copy, line, slen);
1789 token = strtok_r (copy, ":", &rest);
1790 token = strtok_r (NULL, ":", &rest);
1791 sscanf (token, "%u", &ret);
1792 GNUNET_free (copy);
1793 return ret;
1794}
1795
1796
1797static char *
1798get_key (char *line)
1799{
1800 char *copy;
1801 size_t slen;
1802 char *token;
1803 char *ret;
1804 char *rest = NULL;
1805
1806 slen = strlen (line) + 1;
1807 copy = malloc (slen);
1808 memcpy (copy, line, slen);
1809 token = strtok_r (copy, ":", &rest);
1810 ret = malloc (2);
1811 memcpy (ret, token, 2);
1812 GNUNET_free (copy);
1813 return ret;
1814}
1815
1816
1817static char *
1818get_first_string_value (char *line)
1819{
1820 char *copy;
1821 size_t slen, slen_token;
1822 char *token;
1823 char *ret;
1824 char *rest = NULL;
1825
1826 slen = strlen (line) + 1;
1827 copy = malloc (slen);
1828 memcpy (copy, line, slen);
1829 token = strtok_r (copy, ":", &rest);
1830 token = strtok_r (NULL, ":", &rest);
1831 LOG (GNUNET_ERROR_TYPE_ERROR,
1832 "first token %s\n",
1833 token);
1834 slen_token = strlen (token);
1835 ret = malloc (slen_token + 1);
1836 memcpy (ret, token, slen_token + 1);
1837 GNUNET_free (copy);
1838 return ret;
1839}
1840
1841
1842static unsigned int
1843get_second_value (char *line)
1844{
1845 char *copy;
1846 size_t slen;
1847 char *token;
1848 unsigned int ret;
1849 char *rest = NULL;
1850
1851 slen = strlen (line) + 1;
1852 copy = malloc (slen);
1853 memcpy (copy, line, slen);
1854 token = strtok_r (copy, ":", &rest);
1855 token = strtok_r (NULL, ":", &rest);
1856 token = strtok_r (NULL, ":", &rest);
1857 sscanf (token, "%u", &ret);
1858 GNUNET_free (copy);
1859 return ret;
1860}
1861
1862
1863static char *
1864get_value (char *key, char *line)
1865{
1866 char *copy;
1867 size_t slen, slen_token;
1868 char *token;
1869 char *token2;
1870 char *temp;
1871 char *rest = NULL;
1872 char *ret;
1873
1874 slen = strlen (line) + 1;
1875 copy = malloc (slen);
1876 memcpy (copy, line, slen);
1877 temp = strstr (copy, key);
1878 if (NULL == temp)
1879 return NULL;
1880 token = strtok_r (temp, ":", &rest);
1881 token = strtok_r (NULL, ":", &rest);
1882 token2 = strtok_r (token, "}", &rest);
1883 slen_token = strlen (token2);
1884 ret = malloc (slen_token + 1);
1885 memcpy (ret, token2, slen_token + 1);
1886 GNUNET_free (copy);
1887 return ret;
1888}
1889
1890
1891static struct GNUNET_TESTING_NodeConnection *
1892get_connect_value (char *line, struct GNUNET_TESTING_NetjailNode *node)
1893{
1894 struct GNUNET_TESTING_NodeConnection *node_connection;
1895 char *copy;
1896 size_t slen;
1897 char *token;
1898 char *token2;
1899 unsigned int node_n;
1900 unsigned int namespace_n;
1901 char *rest = NULL;
1902 char *rest2 = NULL;
1903 struct GNUNET_TESTING_ADDRESS_PREFIX *prefix;
1904
1905 node_connection = GNUNET_new (struct GNUNET_TESTING_NodeConnection);
1906 node_connection->node = node;
1907
1908 slen = strlen (line) + 1;
1909 copy = malloc (slen);
1910 memcpy (copy, line, slen);
1911 token = strtok_r (copy, ":", &rest);
1912 if (0 == strcmp ("{K", token))
1913 {
1914 node_connection->node_type = GNUNET_TESTING_GLOBAL_NODE;
1915 token = strtok_r (NULL, ":", &rest);
1916 sscanf (token, "%u", &node_n);
1917 LOG (GNUNET_ERROR_TYPE_ERROR,
1918 "node_n %u\n",
1919 node_n);
1920 node_connection->node_n = node_n;
1921 node_connection->namespace_n = 0;
1922 }
1923 else if (0 == strcmp ("{P", token))
1924 {
1925 node_connection->node_type = GNUNET_TESTING_SUBNET_NODE;
1926 token = strtok_r (NULL, ":", &rest);
1927 sscanf (token, "%u", &node_n);
1928 node_connection->node_n = node_n;
1929 token = strtok_r (NULL, ":", &rest);
1930 sscanf (token, "%u", &namespace_n);
1931 node_connection->namespace_n = namespace_n;
1932 LOG (GNUNET_ERROR_TYPE_ERROR,
1933 "node_n %u namespace_n %u\n",
1934 node_n,
1935 namespace_n);
1936 }
1937 while (NULL != (token = strtok_r (NULL, ":", &rest)))
1938 {
1939 prefix = GNUNET_new (struct GNUNET_TESTING_ADDRESS_PREFIX);
1940 token2 = strtok_r (token, "}", &rest2);
1941 if (NULL != token2)
1942 {
1943 slen = strlen (token2) + 1;
1944 prefix->address_prefix = malloc (slen);
1945 memcpy (prefix->address_prefix, token2, slen);
1946 }
1947 else
1948 {
1949 slen = strlen (token) + 1;
1950 prefix->address_prefix = malloc (slen);
1951 memcpy (prefix->address_prefix, token, slen);
1952 }
1953
1954 LOG (GNUNET_ERROR_TYPE_ERROR,
1955 "address_prefix %s\n",
1956 prefix->address_prefix);
1957
1958 GNUNET_CONTAINER_DLL_insert (node_connection->address_prefixes_head,
1959 node_connection->address_prefixes_tail,
1960 prefix);
1961 }
1962
1963 GNUNET_free (copy);
1964 LOG (GNUNET_ERROR_TYPE_ERROR,
1965 "address_prefix %s\n",
1966 prefix->address_prefix);
1967
1968 return node_connection;
1969}
1970
1971
1972static void
1973node_connections (char *line, struct GNUNET_TESTING_NetjailNode *node)
1974{
1975 char *value, *value2;
1976 char *temp;
1977 char *copy;
1978 size_t slen;
1979 char *rest = NULL;
1980 char *rest2 = NULL;
1981 struct GNUNET_TESTING_NodeConnection *node_connection;
1982
1983
1984 temp = strstr (line, "connect");
1985 if (NULL != temp)
1986 {
1987 slen = strlen (temp) + 1;
1988 copy = malloc (slen);
1989 memcpy (copy, temp, slen);
1990 strtok_r (copy, ":", &rest);
1991 value = strtok_r (rest, "|", &rest2);
1992
1993 while (NULL != value)
1994 {
1995 node_connection = get_connect_value (value, node);
1996 GNUNET_CONTAINER_DLL_insert (node->node_connections_head,
1997 node->node_connections_tail,
1998 node_connection);
1999 value2 = strstr (value, "}}");
2000 if (NULL != value2)
2001 break;
2002 value = strtok_r (NULL, "|", &rest2);
2003
2004 }
2005 }
2006}
2007
2008
2009/**
2010 * Getting the topology from file.
2011 *
2012 * @param filename The name of the topology file.
2013 * @return The GNUNET_TESTING_NetjailTopology
2014 */
2015struct GNUNET_TESTING_NetjailTopology *
2016GNUNET_TESTING_get_topo_from_file (const char *filename)
2017{
2018 uint64_t fs;
2019 char *data;
2020 char *token;
2021 char *key;
2022 unsigned int out;
2023 char *rest = NULL;
2024 char *value;
2025 int ret;
2026 struct GNUNET_TESTING_NetjailTopology *topo = GNUNET_new (struct
2027 GNUNET_TESTING_NetjailTopology);
2028 struct GNUNET_TESTING_NetjailNode *node;
2029 struct GNUNET_TESTING_NetjailRouter *router;
2030 struct GNUNET_TESTING_NetjailNamespace *namespace;
2031 struct GNUNET_ShortHashCode *hkey;
2032 struct GNUNET_HashCode hc;
2033
2034 topo->map_namespaces =
2035 GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO);
2036 topo->map_globals =
2037 GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO);
2038
2039 if (GNUNET_YES != GNUNET_DISK_file_test (filename))
2040 {
2041 LOG (GNUNET_ERROR_TYPE_ERROR,
2042 _ ("Topology file %s not found\n"),
2043 filename);
2044 return NULL;
2045 }
2046 if (GNUNET_OK !=
2047 GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES))
2048 {
2049 LOG (GNUNET_ERROR_TYPE_ERROR,
2050 _ ("Topology file %s has no data\n"),
2051 filename);
2052 return NULL;
2053 }
2054 data = GNUNET_malloc (fs);
2055 if (fs != GNUNET_DISK_fn_read (filename, data, fs))
2056 {
2057 LOG (GNUNET_ERROR_TYPE_ERROR,
2058 _ ("Topology file %s cannot be read\n"),
2059 filename);
2060 GNUNET_free (data);
2061 return NULL;
2062 }
2063
2064 LOG (GNUNET_ERROR_TYPE_ERROR,
2065 "data: %s\n",
2066 data);
2067
2068 token = strtok_r (data, "\n", &rest);
2069
2070 while (NULL != token)
2071 {
2072 key = get_key (token);
2073 LOG (GNUNET_ERROR_TYPE_ERROR,
2074 "In the loop with token: %s beginning with %s\n",
2075 token,
2076 key);
2077 if (0 == strcmp (key, "M"))
2078 {
2079 LOG (GNUNET_ERROR_TYPE_ERROR,
2080 "Get first Value for M.\n");
2081 out = get_first_value (token);
2082 LOG (GNUNET_ERROR_TYPE_ERROR,
2083 "M: %u\n",
2084 out);
2085 topo->nodes_m = out;
2086 }
2087 else if (0 == strcmp (key, "N"))
2088 {
2089 LOG (GNUNET_ERROR_TYPE_ERROR,
2090 "Get first Value for N.\n");
2091 out = get_first_value (token);
2092 LOG (GNUNET_ERROR_TYPE_ERROR,
2093 "N: %u\n",
2094 out);
2095 topo->namespaces_n = out;
2096 }
2097 else if (0 == strcmp (key, "X"))
2098 {
2099 LOG (GNUNET_ERROR_TYPE_ERROR,
2100 "Get first Value for X.\n");
2101 out = get_first_value (token);
2102 LOG (GNUNET_ERROR_TYPE_ERROR,
2103 "X: %u\n",
2104 out);
2105 topo->nodes_x = out;
2106 }
2107 else if (0 == strcmp (key, "T"))
2108 {
2109 LOG (GNUNET_ERROR_TYPE_ERROR,
2110 "Get first string value for T.\n");
2111 value = get_first_string_value (token);
2112 LOG (GNUNET_ERROR_TYPE_ERROR,
2113 "value: %s\n",
2114 value);
2115 topo->plugin = value;
2116 }
2117 else if (0 == strcmp (key, "K"))
2118 {
2119 hkey = GNUNET_new (struct GNUNET_ShortHashCode);
2120 node = GNUNET_new (struct GNUNET_TESTING_NetjailNode);
2121
2122 LOG (GNUNET_ERROR_TYPE_ERROR,
2123 "Get first Value for K.\n");
2124 out = get_first_value (token);
2125 LOG (GNUNET_ERROR_TYPE_ERROR,
2126 "K: %u\n",
2127 out);
2128 node->node_n = out;
2129 GNUNET_CRYPTO_hash (&out, sizeof(out), &hc);
2130 memcpy (hkey,
2131 &hc,
2132 sizeof (*hkey));
2133 node->is_global = GNUNET_YES;
2134
2135 if (GNUNET_YES == GNUNET_CONTAINER_multishortmap_contains (
2136 topo->map_globals,
2137 hkey))
2138 GNUNET_break (0);
2139 else
2140 GNUNET_CONTAINER_multishortmap_put (topo->map_globals,
2141 hkey,
2142 node,
2143 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
2144 LOG (GNUNET_ERROR_TYPE_ERROR,
2145 "Get value for key value on K.\n");
2146 value = get_value ("plugin", token);
2147 LOG (GNUNET_ERROR_TYPE_ERROR,
2148 "value: %s\n",
2149 value);
2150 node->plugin = value;
2151 node_connections (token, node);
2152 }
2153 else if (0 == strcmp (key, "R"))
2154 {
2155 hkey = GNUNET_new (struct GNUNET_ShortHashCode);
2156 router = GNUNET_new (struct GNUNET_TESTING_NetjailRouter);
2157 node = GNUNET_new (struct GNUNET_TESTING_NetjailNode);
2158
2159 LOG (GNUNET_ERROR_TYPE_ERROR,
2160 "Get first Value for R.\n");
2161 out = get_first_value (token);
2162 LOG (GNUNET_ERROR_TYPE_ERROR,
2163 "R: %u\n",
2164 out);
2165 node->node_n = out;
2166 GNUNET_CRYPTO_hash (&out, sizeof(out), &hc);
2167 memcpy (hkey,
2168 &hc,
2169 sizeof (*hkey));
2170 LOG (GNUNET_ERROR_TYPE_ERROR,
2171 "Get value for key tcp_port on R.\n");
2172 value = get_value ("tcp_port", token);
2173 LOG (GNUNET_ERROR_TYPE_ERROR,
2174 "tcp_port: %s\n",
2175 value);
2176 ret = sscanf (value, "%u", &(router->tcp_port));
2177
2178 GNUNET_break (0 != ret && 1 >= router->tcp_port);
2179
2180 LOG (GNUNET_ERROR_TYPE_ERROR,
2181 "Get value for key udp_port on R.\n");
2182 value = get_value ("udp_port", token);
2183 ret = sscanf (value, "%u", &(router->udp_port));
2184 GNUNET_break (0 != ret && 1 >= router->udp_port);
2185 LOG (GNUNET_ERROR_TYPE_ERROR,
2186 "udp_port: %s\n",
2187 value);
2188
2189 if (GNUNET_YES == GNUNET_CONTAINER_multishortmap_contains (
2190 topo->map_namespaces,
2191 hkey))
2192 {
2193 namespace = GNUNET_CONTAINER_multishortmap_get (topo->map_namespaces,
2194 hkey);
2195 }
2196 else
2197 {
2198 namespace = GNUNET_new (struct GNUNET_TESTING_NetjailNamespace);
2199 namespace->namespace_n = out;
2200 namespace->nodes = GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO);
2201 GNUNET_CONTAINER_multishortmap_put (topo->map_namespaces,
2202 hkey,
2203 namespace,
2204 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
2205 }
2206 namespace->router = router;
2207
2208 }
2209 else if (0 == strcmp (key, "P"))
2210 {
2211 hkey = GNUNET_new (struct GNUNET_ShortHashCode);
2212 node = GNUNET_new (struct GNUNET_TESTING_NetjailNode);
2213
2214 LOG (GNUNET_ERROR_TYPE_ERROR,
2215 "Get first Value for P.\n");
2216 out = get_first_value (token);
2217 LOG (GNUNET_ERROR_TYPE_ERROR,
2218 "P: %u\n",
2219 out);
2220 GNUNET_CRYPTO_hash (&out, sizeof(out), &hc);
2221 memcpy (hkey,
2222 &hc,
2223 sizeof (*hkey));
2224
2225 if (GNUNET_YES == GNUNET_CONTAINER_multishortmap_contains (
2226 topo->map_namespaces,
2227 hkey))
2228 {
2229 namespace = GNUNET_CONTAINER_multishortmap_get (topo->map_namespaces,
2230 hkey);
2231 }
2232 else
2233 {
2234 namespace = GNUNET_new (struct GNUNET_TESTING_NetjailNamespace);
2235 namespace->nodes = GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO);
2236 namespace->namespace_n = out;
2237 GNUNET_CONTAINER_multishortmap_put (topo->map_namespaces,
2238 hkey,
2239 namespace,
2240 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
2241 }
2242 LOG (GNUNET_ERROR_TYPE_ERROR,
2243 "Get second Value for P.\n");
2244 out = get_second_value (token);
2245 LOG (GNUNET_ERROR_TYPE_ERROR,
2246 "P: %u\n",
2247 out);
2248 GNUNET_CRYPTO_hash (&out, sizeof(out), &hc);
2249 memcpy (hkey,
2250 &hc,
2251 sizeof (*hkey));
2252 if (GNUNET_YES == GNUNET_CONTAINER_multishortmap_contains (
2253 namespace->nodes,
2254 hkey))
2255 {
2256 GNUNET_break (0);
2257 }
2258 else
2259 {
2260 node = GNUNET_new (struct GNUNET_TESTING_NetjailNode);
2261 GNUNET_CONTAINER_multishortmap_put (namespace->nodes,
2262 hkey,
2263 node,
2264 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
2265 LOG (GNUNET_ERROR_TYPE_ERROR,
2266 "Get value for key plugin on P.\n");
2267 value = get_value ("plugin", token);
2268 LOG (GNUNET_ERROR_TYPE_ERROR,
2269 "plugin: %s\n",
2270 value);
2271 node->plugin = value;
2272 node->node_n = out;
2273 node->namespace_n = namespace->namespace_n;
2274 }
2275 node_connections (token, node);
2276 }
2277 token = strtok_r (NULL, "\n", &rest);
2278 }
2279
2280 return topo;
2281}
2282
2283
2284/* end of testing.c */
diff --git a/src/testing/testing.conf b/src/testing/testing.conf
deleted file mode 100644
index 7e25f8c13..000000000
--- a/src/testing/testing.conf
+++ /dev/null
@@ -1,11 +0,0 @@
1[TESTING]
2# How long before failing a connection?
3CONNECT_TIMEOUT = 30 s
4# How many connect attempts should we make?
5CONNECT_ATTEMPTS = 3
6# How many connections can happen simultaneously?
7MAX_OUTSTANDING_CONNECTIONS = 50
8
9# Should we clean up the files on peer group shutdown?
10DELETE_FILES = YES
11
diff --git a/src/testing/testing.h b/src/testing/testing.h
deleted file mode 100644
index b12466530..000000000
--- a/src/testing/testing.h
+++ /dev/null
@@ -1,74 +0,0 @@
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 * @author t3sserakt
23 */
24
25#include "gnunet_util_lib.h"
26
27/**
28 * Global state of the interpreter, used by a command
29 * to access information about other commands.
30 */
31// SUGGESTION: consider making this struct opaque (only known inside of libgnunettesting,
32// say main loop and a few select commands, like next/fail/batch); + helper
33// function to access 'cfg'?
34struct GNUNET_TESTING_Interpreter
35{
36
37 /**
38 * Commands the interpreter will run.
39 */
40 struct GNUNET_TESTING_Command *commands;
41
42 /**
43 * Interpreter task (if one is scheduled).
44 */
45 struct GNUNET_SCHEDULER_Task *task;
46
47 /**
48 * Finish task of a blocking call to a commands finish method.
49 */
50 struct GNUNET_SCHEDULER_Task *finish_task;
51
52 /**
53 * Our configuration.
54 */
55 const struct GNUNET_CONFIGURATION_Handle *cfg;
56
57 /**
58 * Task run on timeout.
59 */
60 struct GNUNET_SCHEDULER_Task *timeout_task;
61
62 /**
63 * Instruction pointer. Tells #interpreter_run() which instruction to run
64 * next. Need (signed) int because it gets -1 when rewinding the
65 * interpreter to the first CMD.
66 */
67 int ip;
68
69 /**
70 * Result of the testcases, #GNUNET_OK on success
71 */
72 int result;
73
74};
diff --git a/src/testing/testing_api_cmd_batch.c b/src/testing/testing_api_cmd_batch.c
deleted file mode 100644
index af260f80d..000000000
--- a/src/testing/testing_api_cmd_batch.c
+++ /dev/null
@@ -1,256 +0,0 @@
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_batch.c
23 * @brief Implement batch-execution of CMDs.
24 * @author Marcello Stanisci (GNU Taler testing)
25 * @author t3sserakt
26 */
27#include "platform.h"
28#include "gnunet_testing_ng_lib.h"
29#include "testing.h"
30
31/**
32 * State for a "batch" CMD.
33 */
34struct BatchState
35{
36 /**
37 * CMDs batch.
38 */
39 struct GNUNET_TESTING_Command *batch;
40
41 /**
42 * Internal command pointer.
43 */
44 unsigned int batch_ip;
45};
46
47
48/**
49 * Run the command.
50 *
51 * @param cls closure.
52 * @param cmd the command being executed.
53 * @param is the interpreter state.
54 */
55static void
56batch_run (void *cls,
57 const struct GNUNET_TESTING_Command *cmd,
58 struct GNUNET_TESTING_Interpreter *is)
59{
60 struct BatchState *bs = cls;
61
62 if (NULL != bs->batch[bs->batch_ip].label)
63 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
64 "Running batched command: %s\n",
65 bs->batch[bs->batch_ip].label);
66
67 /* hit end command, leap to next top-level command. */
68 if (NULL == bs->batch[bs->batch_ip].label)
69 {
70 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
71 "Exiting from batch: %s\n",
72 cmd->label);
73 return;
74 }
75 bs->batch[bs->batch_ip].start_time
76 = bs->batch[bs->batch_ip].last_req_time
77 = GNUNET_TIME_absolute_get ();
78 bs->batch[bs->batch_ip].num_tries = 1;
79 bs->batch[bs->batch_ip].run (bs->batch[bs->batch_ip].cls,
80 &bs->batch[bs->batch_ip],
81 is);
82}
83
84
85/**
86 * Cleanup the state from a "reserve status" CMD, and possibly
87 * cancel a pending operation thereof.
88 *
89 * @param cls closure.
90 * @param cmd the command which is being cleaned up.
91 */
92static void
93batch_cleanup (void *cls,
94 const struct GNUNET_TESTING_Command *cmd)
95{
96 struct BatchState *bs = cls;
97
98 (void) cmd;
99 for (unsigned int i = 0;
100 NULL != bs->batch[i].label;
101 i++)
102 bs->batch[i].cleanup (bs->batch[i].cls,
103 &bs->batch[i]);
104 GNUNET_free (bs->batch);
105 GNUNET_free (bs);
106}
107
108
109/**
110 * Offer internal data from a "batch" CMD, to other commands.
111 *
112 * @param cls closure.
113 * @param[out] ret result.
114 * @param trait name of the trait.
115 * @param index index number of the object to offer.
116 * @return #GNUNET_OK on success.
117 */
118static int
119batch_traits (void *cls,
120 const void **ret,
121 const char *trait,
122 unsigned int index)
123{
124#define CURRENT_CMD_INDEX 0
125#define BATCH_INDEX 1
126
127 struct BatchState *bs = cls;
128
129 struct GNUNET_TESTING_Trait traits[] = {
130 GNUNET_TESTING_make_trait_cmd
131 (CURRENT_CMD_INDEX, &bs->batch[bs->batch_ip]),
132 GNUNET_TESTING_make_trait_cmd
133 (BATCH_INDEX, bs->batch),
134 GNUNET_TESTING_trait_end ()
135 };
136
137 /* Always return current command. */
138 return GNUNET_TESTING_get_trait (traits,
139 ret,
140 trait,
141 index);
142}
143
144
145/**
146 * Create a "batch" command. Such command takes a
147 * end_CMD-terminated array of CMDs and executed them.
148 * Once it hits the end CMD, it passes the control
149 * to the next top-level CMD, regardless of it being
150 * another batch or ordinary CMD.
151 *
152 * @param label the command label.
153 * @param batch array of CMDs to execute.
154 *
155 * @return the command.
156 */
157struct GNUNET_TESTING_Command
158GNUNET_TESTING_cmd_batch (const char *label,
159 struct GNUNET_TESTING_Command *batch)
160{
161 struct BatchState *bs;
162 unsigned int i;
163
164 bs = GNUNET_new (struct BatchState);
165
166 /* Get number of commands. */
167 for (i = 0; NULL != batch[i].label; i++)
168 /* noop */
169 ;
170
171 bs->batch = GNUNET_new_array (i + 1,
172 struct GNUNET_TESTING_Command);
173 memcpy (bs->batch,
174 batch,
175 sizeof (struct GNUNET_TESTING_Command) * i);
176 {
177 struct GNUNET_TESTING_Command cmd = {
178 .cls = bs,
179 .label = label,
180 .run = &batch_run,
181 .cleanup = &batch_cleanup,
182 .traits = &batch_traits
183 };
184
185 return cmd;
186 }
187}
188
189
190/**
191 * Advance internal pointer to next command.
192 *
193 * @param is interpreter state.
194 */
195void
196GNUNET_TESTING_cmd_batch_next (struct GNUNET_TESTING_Interpreter *is)
197{
198 struct BatchState *bs = is->commands[is->ip].cls;
199
200 if (NULL == bs->batch[bs->batch_ip].label)
201 {
202 is->commands[is->ip].finish_time = GNUNET_TIME_absolute_get ();
203 is->ip++;
204 return;
205 }
206 bs->batch[bs->batch_ip].finish_time = GNUNET_TIME_absolute_get ();
207 bs->batch_ip++;
208}
209
210
211/**
212 * Test if this command is a batch command.
213 *
214 * @return false if not, true if it is a batch command
215 */
216int
217GNUNET_TESTING_cmd_is_batch (const struct GNUNET_TESTING_Command *cmd)
218{
219 return cmd->run == &batch_run;
220}
221
222
223/**
224 * Obtain what command the batch is at.
225 *
226 * @return cmd current batch command
227 */
228struct GNUNET_TESTING_Command *
229GNUNET_TESTING_cmd_batch_get_current (const struct GNUNET_TESTING_Command *cmd)
230{
231 struct BatchState *bs = cmd->cls;
232
233 GNUNET_assert (cmd->run == &batch_run);
234 return &bs->batch[bs->batch_ip];
235}
236
237
238/**
239 * Set what command the batch should be at.
240 *
241 * @param cmd current batch command
242 * @param new_ip where to move the IP
243 */
244void
245GNUNET_TESTING_cmd_batch_set_current (const struct GNUNET_TESTING_Command *cmd,
246 unsigned int new_ip)
247{
248 struct BatchState *bs = cmd->cls;
249
250 /* sanity checks */
251 GNUNET_assert (cmd->run == &batch_run);
252 for (unsigned int i = 0; i < new_ip; i++)
253 GNUNET_assert (NULL != bs->batch[i].label);
254 /* actual logic */
255 bs->batch_ip = new_ip;
256}
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
deleted file mode 100644
index e9d3f0ed3..000000000
--- a/src/testing/testing_api_cmd_block_until_all_peers_started.c
+++ /dev/null
@@ -1,139 +0,0 @@
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_block_until_external_trigger.c b/src/testing/testing_api_cmd_block_until_external_trigger.c
deleted file mode 100644
index 2439afeaf..000000000
--- a/src/testing/testing_api_cmd_block_until_external_trigger.c
+++ /dev/null
@@ -1,139 +0,0 @@
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 *stop_blocking;
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->stop_blocking;
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_external_trigger (const char *label,
121 unsigned int *
122 stop_blocking)
123{
124 struct BlockState *bs;
125
126 bs = GNUNET_new (struct BlockState);
127 bs->stop_blocking = stop_blocking;
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_hello_world.c b/src/testing/testing_api_cmd_hello_world.c
deleted file mode 100644
index 4347ac818..000000000
--- a/src/testing/testing_api_cmd_hello_world.c
+++ /dev/null
@@ -1,121 +0,0 @@
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 implementation of a hello world command.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_testing_ng_lib.h"
28
29struct HelloWorldState
30{
31 char *message;
32 const char *birthLabel;
33};
34
35/**
36*
37*
38* @param cls closure
39* @param cmd current CMD being cleaned up.
40*/
41static void
42hello_world_cleanup (void *cls,
43 const struct GNUNET_TESTING_Command *cmd)
44{
45 struct HelloWorldState *hs = cls;
46 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
47 "Cleaning up message %s\n",
48 hs->message);
49}
50
51/**
52*
53*
54* @param cls closure.
55* @param[out] ret result
56* @param trait name of the trait.
57* @param index index number of the object to offer.
58* @return #GNUNET_OK on success.
59*/
60static int
61hello_world_traits (void *cls,
62 const void **ret,
63 const char *trait,
64 unsigned int index)
65{
66 return GNUNET_OK;
67}
68
69/**
70* Run the "hello world" CMD.
71*
72* @param cls closure.
73* @param cmd CMD being run.
74* @param is interpreter state.
75*/
76static void
77hello_world_run (void *cls,
78 const struct GNUNET_TESTING_Command *cmd,
79 struct GNUNET_TESTING_Interpreter *is)
80{
81 struct HelloWorldState *hs = cls;
82 const struct GNUNET_TESTING_Command *birth_cmd;
83
84 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
85 "%s\n",
86 hs->message);
87 birth_cmd = GNUNET_TESTING_interpreter_lookup_command (hs->birthLabel);
88 GNUNET_TESTING_get_trait_what_am_i (birth_cmd, &hs->message);
89 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
90 "Now I am a %s\n",
91 hs->message);
92}
93
94/**
95 * Create command.
96 *
97 * @param label name for command.
98 * @param message initial message.
99 * @return command.
100 */
101struct GNUNET_TESTING_Command
102GNUNET_TESTING_cmd_hello_world (const char *label,
103 const char *birthLabel,
104 char *message)
105{
106 struct HelloWorldState *hs;
107
108 hs = GNUNET_new (struct HelloWorldState);
109 hs->message = "Hello World, I was nobody!";
110 hs->birthLabel = birthLabel;
111
112 struct GNUNET_TESTING_Command cmd = {
113 .cls = hs,
114 .label = label,
115 .run = &hello_world_run,
116 .cleanup = &hello_world_cleanup,
117 .traits = &hello_world_traits
118 };
119
120 return cmd;
121}
diff --git a/src/testing/testing_api_cmd_hello_world_birth.c b/src/testing/testing_api_cmd_hello_world_birth.c
deleted file mode 100644
index 9d60059a5..000000000
--- a/src/testing/testing_api_cmd_hello_world_birth.c
+++ /dev/null
@@ -1,159 +0,0 @@
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 implementation of a hello world command.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_testing_ng_lib.h"
29
30struct HelloWorldBirthState
31{
32 struct GNUNET_TIME_Absolute *date;
33 char *what_am_i;
34};
35
36/**
37*
38*
39* @param cls closure
40* @param cmd current CMD being cleaned up.
41*/
42static void
43hello_world_birth_cleanup (void *cls,
44 const struct GNUNET_TESTING_Command *cmd)
45{
46 struct HelloWorldBirthState *hbs = cls;
47 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
48 "Finished birth of %s\n",
49 hbs->what_am_i);
50}
51
52/**
53*
54*
55* @param cls closure.
56* @param[out] ret result
57* @param trait name of the trait.
58* @param index index number of the object to offer.
59* @return #GNUNET_OK on success.
60*/
61static int
62hello_world_birth_traits (void *cls,
63 const void **ret,
64 const char *trait,
65 unsigned int index)
66{
67 struct HelloWorldBirthState *hbs = cls;
68 const char *what_am_i = hbs->what_am_i;
69
70 struct GNUNET_TESTING_Trait traits[] = {
71 {
72 .index = 0,
73 .trait_name = "what_am_i",
74 .ptr = (const void *) what_am_i,
75 },
76 GNUNET_TESTING_trait_end ()
77 };
78
79 return GNUNET_TESTING_get_trait (traits,
80 ret,
81 trait,
82 index);
83}
84
85/**
86* Run the "hello world" CMD.
87*
88* @param cls closure.
89* @param cmd CMD being run.
90* @param is interpreter state.
91*/
92static void
93hello_world_birth_run (void *cls,
94 const struct GNUNET_TESTING_Command *cmd,
95 struct GNUNET_TESTING_Interpreter *is)
96{
97 struct HelloWorldBirthState *hbs = cls;
98 struct GNUNET_TIME_Relative relative;
99
100 relative = GNUNET_TIME_absolute_get_difference (*hbs->date,
101 GNUNET_TIME_absolute_get ());
102
103 if (0 == relative.rel_value_us % 10)
104 {
105 hbs->what_am_i = "creature!";
106 }
107 else if (0 == relative.rel_value_us % 2)
108 {
109 hbs->what_am_i = "girl!";
110 }
111 else
112 {
113 hbs->what_am_i = "boy!";
114 }
115}
116
117/**
118 * Offer data from trait
119 *
120 * @param cmd command to extract the message from.
121 * @param pt pointer to message.
122 * @return #GNUNET_OK on success.
123 */
124int
125GNUNET_TESTING_get_trait_what_am_i (const struct GNUNET_TESTING_Command *cmd,
126 char **what_am_i)
127{
128 return cmd->traits (cmd->cls,
129 (const void **) what_am_i,
130 "what_am_i",
131 (unsigned int) 0);
132}
133
134/**
135 * Create command.
136 *
137 * @param label name for command.
138 * @param now when the command was started.
139 * @return command.
140 */
141struct GNUNET_TESTING_Command
142GNUNET_TESTING_cmd_hello_world_birth (const char *label,
143 struct GNUNET_TIME_Absolute *now)
144{
145 struct HelloWorldBirthState *hbs;
146
147 hbs = GNUNET_new (struct HelloWorldBirthState);
148 hbs->date = now;
149
150 struct GNUNET_TESTING_Command cmd = {
151 .cls = hbs,
152 .label = label,
153 .run = &hello_world_birth_run,
154 .cleanup = &hello_world_birth_cleanup,
155 .traits = &hello_world_birth_traits
156 };
157
158 return cmd;
159}
diff --git a/src/testing/testing_api_cmd_local_test_finished.c b/src/testing/testing_api_cmd_local_test_finished.c
deleted file mode 100644
index 383de4c10..000000000
--- a/src/testing/testing_api_cmd_local_test_finished.c
+++ /dev/null
@@ -1,151 +0,0 @@
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
deleted file mode 100644
index 536b356a6..000000000
--- a/src/testing/testing_api_cmd_netjail_start.c
+++ /dev/null
@@ -1,229 +0,0 @@
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
deleted file mode 100644
index 531621eb5..000000000
--- a/src/testing/testing_api_cmd_netjail_start_testsystem.c
+++ /dev/null
@@ -1,610 +0,0 @@
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 * Continuation function from GNUNET_HELPER_send()
282 *
283 * @param cls closure
284 * @param result GNUNET_OK on success,
285 * GNUNET_NO if helper process died
286 * GNUNET_SYSERR during GNUNET_HELPER_stop
287 */
288static void
289clear_msg (void *cls, int result)
290{
291 struct TestingSystemCount *tbc = cls;
292 struct NetJailState *ns = tbc->ns;
293
294 GNUNET_assert (NULL != ns->shandle[tbc->count - 1]);
295 ns->shandle[tbc->count - 1] = NULL;
296 GNUNET_free (ns->msg[tbc->count - 1]);
297 ns->msg[tbc->count - 1] = NULL;
298}
299
300
301/**
302 * Functions with this signature are called whenever a
303 * complete message is received by the tokenizer.
304 *
305 * Do not call GNUNET_SERVER_mst_destroy in callback
306 *
307 * @param cls closure
308 * @param client identification of the client
309 * @param message the actual message
310 *
311 * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
312 */
313static int
314helper_mst (void *cls, const struct GNUNET_MessageHeader *message)
315{
316 struct TestingSystemCount *tbc = cls;
317 struct NetJailState *ns = tbc->ns;
318 struct HelperMessage *hp_msg;
319
320 if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY == ntohs (message->type))
321 {
322 ns->number_of_testsystems_started++;
323 }
324 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED == ntohs (
325 message->type))
326 {
327 ns->number_of_peers_started++;
328 }
329 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED == ntohs (
330 message->type))
331 {
332 ns->number_of_local_test_finished++;
333 }
334 else
335 {
336 hp_msg = GNUNET_new (struct HelperMessage);
337 hp_msg->bytes_msg = message->size;
338 memcpy (&hp_msg[1], message, message->size);
339 GNUNET_CONTAINER_DLL_insert (ns->hp_messages_head, ns->hp_messages_tail,
340 hp_msg);
341 }
342
343 return GNUNET_OK;
344}
345
346
347/**
348 * Callback called if there was an exception during execution of the helper.
349 *
350 */
351static void
352exp_cb (void *cls)
353{
354 struct NetJailState *ns = cls;
355 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called exp_cb.\n");
356 *ns->rv = 1;
357}
358
359
360/**
361 * Function to initialize a init message for the helper.
362 *
363 * @param m_char The actual node in a namespace. //TODO Change this to unsigned int
364 * @param n_char The actual namespace. //TODO Change this to unsigned int
365 * @param plugin_name Name of the test case plugin the helper will load.
366 *
367 */
368static struct GNUNET_CMDS_HelperInit *
369create_helper_init_msg_ (char *m_char,
370 char *n_char,
371 const char *plugin_name)
372{
373 struct GNUNET_CMDS_HelperInit *msg;
374 uint16_t plugin_name_len;
375 uint16_t msg_size;
376
377 GNUNET_assert (NULL != plugin_name);
378 plugin_name_len = strlen (plugin_name);
379 msg_size = sizeof(struct GNUNET_CMDS_HelperInit) + plugin_name_len;
380 msg = GNUNET_malloc (msg_size);
381 msg->header.size = htons (msg_size);
382 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT);
383 msg->plugin_name_size = htons (plugin_name_len);
384 GNUNET_memcpy ((char *) &msg[1],
385 plugin_name,
386 plugin_name_len);
387 return msg;
388}
389
390
391/**
392 * Function which start a single helper process.
393 *
394 */
395static void
396start_helper (struct NetJailState *ns, struct
397 GNUNET_CONFIGURATION_Handle *config,
398 char *m_char,
399 char *n_char)
400{
401 struct GNUNET_HELPER_Handle *helper;
402 struct GNUNET_CMDS_HelperInit *msg;
403 struct TestingSystemCount *tbc;
404 char *const script_argv[] = {NETJAIL_EXEC_SCRIPT,
405 m_char,
406 n_char,
407 GNUNET_OS_get_libexec_binary_path (
408 HELPER_CMDS_BINARY),
409 ns->global_n,
410 ns->local_m,
411 NULL};
412 unsigned int m = atoi (m_char);
413 unsigned int n = atoi (n_char);
414 unsigned int helper_check = GNUNET_OS_check_helper_binary (
415 NETJAIL_EXEC_SCRIPT,
416 GNUNET_YES,
417 NULL);
418
419 tbc = GNUNET_new (struct TestingSystemCount);
420 tbc->ns = ns;
421 tbc->count = (n - 1) * atoi (ns->local_m) + m;
422
423 GNUNET_CONTAINER_DLL_insert (ns->tbcs_head, ns->tbcs_tail,
424 tbc);
425
426
427 if (GNUNET_NO == helper_check)
428 {
429 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
430 "No SUID for %s!\n",
431 NETJAIL_EXEC_SCRIPT);
432 *ns->rv = 1;
433 }
434 else if (GNUNET_NO == helper_check)
435 {
436 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
437 "%s not found!\n",
438 NETJAIL_EXEC_SCRIPT);
439 *ns->rv = 1;
440 }
441
442 GNUNET_array_append (ns->helper, ns->n_helper, GNUNET_HELPER_start (
443 GNUNET_YES,
444 NETJAIL_EXEC_SCRIPT,
445 script_argv,
446 &helper_mst,
447 &exp_cb,
448 tbc));
449
450 helper = ns->helper[tbc->count - 1];
451
452 msg = create_helper_init_msg_ (m_char,
453 n_char,
454 ns->plugin_name);
455 GNUNET_array_append (ns->msg, ns->n_msg, &msg->header);
456
457 GNUNET_array_append (ns->shandle, ns->n_shandle, GNUNET_HELPER_send (
458 helper,
459 &msg->header,
460 GNUNET_NO,
461 &clear_msg,
462 tbc));
463
464 if (NULL == ns->shandle[tbc->count - 1])
465 {
466 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
467 "Send handle is NULL!\n");
468 GNUNET_free (msg);
469 *ns->rv = 1;
470 }
471}
472
473
474/**
475* This function starts a helper process for each node.
476*
477* @param cls closure.
478* @param cmd CMD being run.
479* @param is interpreter state.
480*/
481static void
482netjail_exec_run (void *cls,
483 const struct GNUNET_TESTING_Command *cmd,
484 struct GNUNET_TESTING_Interpreter *is)
485{
486 char str_m[12];
487 char str_n[12];
488 struct NetJailState *ns = cls;
489 struct GNUNET_CONFIGURATION_Handle *config =
490 GNUNET_CONFIGURATION_create ();
491
492 for (int i = 1; i <= atoi (ns->global_n); i++)
493 {
494 for (int j = 1; j <= atoi (ns->local_m); j++)
495 {
496 sprintf (str_n, "%d", i);
497 sprintf (str_m, "%d", j);
498 start_helper (ns, config,
499 str_m,
500 str_n);
501 }
502 }
503}
504
505
506/**
507 * This function checks on three different information.
508 *
509 * 1. Did all helpers start. This is only logged.
510 * 2. Did all peer start.
511 * In this case a GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED is send to all peers.
512 * 3. Did all peers finished the test case. In this case interpreter_next will be called.
513 *
514 */
515static int
516netjail_start_finish (void *cls,
517 GNUNET_SCHEDULER_TaskCallback cont,
518 void *cont_cls)
519{
520 unsigned int ret = GNUNET_NO;
521 struct NetJailState *ns = cls;
522 unsigned int total_number = atoi (ns->local_m) * atoi (ns->global_n);
523 struct GNUNET_CMDS_ALL_PEERS_STARTED *reply;
524 size_t msg_length;
525 struct GNUNET_HELPER_Handle *helper;
526 struct TestingSystemCount *tbc;
527
528 if (ns->number_of_local_test_finished == total_number)
529 {
530 ret = GNUNET_YES;
531 cont (cont_cls);
532 }
533
534 if (ns->number_of_testsystems_started == total_number)
535 {
536 ns->number_of_testsystems_started = 0;
537 }
538
539 if (ns->number_of_peers_started == total_number)
540 {
541 for (int i = 1; i <= atoi (ns->global_n); i++)
542 {
543 for (int j = 1; j <= atoi (ns->local_m); j++)
544 {
545 tbc = GNUNET_new (struct TestingSystemCount);
546 tbc->ns = ns;
547 // 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.
548 tbc->count = (i - 1) * atoi (ns->local_m) + j + total_number;
549
550 helper = ns->helper[tbc->count - 1 - total_number];
551 msg_length = sizeof(struct GNUNET_CMDS_ALL_PEERS_STARTED);
552 reply = GNUNET_new (struct GNUNET_CMDS_ALL_PEERS_STARTED);
553 reply->header.type = htons (
554 GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED);
555 reply->header.size = htons ((uint16_t) msg_length);
556
557 GNUNET_array_append (ns->msg, ns->n_msg, &reply->header);
558
559 struct GNUNET_HELPER_SendHandle *sh = GNUNET_HELPER_send (
560 helper,
561 &reply->header,
562 GNUNET_NO,
563 &clear_msg,
564 tbc);
565
566 GNUNET_array_append (ns->shandle, ns->n_shandle, sh);
567 }
568 }
569 ns->number_of_peers_started = 0;
570 }
571 return ret;
572}
573
574
575/**
576 * Create command.
577 *
578 * @param label Name for the command.
579 * @param local_m Number of nodes in a network namespace. //TODO make this a unsigned int
580 * @param global_n Number of network namespaces. //TODO make this a unsigned int
581 * @param plugin_name Name of the test case plugin the helper will load.
582 * @param rv Pointer to the return value of the test.
583 * @return command.
584 */
585struct GNUNET_TESTING_Command
586GNUNET_TESTING_cmd_netjail_start_testing_system (const char *label,
587 char *local_m,
588 char *global_n,
589 char *plugin_name,
590 unsigned int *rv)
591{
592 struct NetJailState *ns;
593
594 ns = GNUNET_new (struct NetJailState);
595 ns->local_m = local_m;
596 ns->global_n = global_n;
597 ns->plugin_name = plugin_name;
598 ns->rv = rv;
599
600 struct GNUNET_TESTING_Command cmd = {
601 .cls = ns,
602 .label = label,
603 .run = &netjail_exec_run,
604 .finish = &netjail_start_finish,
605 .cleanup = &netjail_exec_cleanup,
606 .traits = &netjail_exec_traits
607 };
608
609 return cmd;
610}
diff --git a/src/testing/testing_api_cmd_netjail_start_testsystem_v2.c b/src/testing/testing_api_cmd_netjail_start_testsystem_v2.c
deleted file mode 100644
index ccb3f5ae8..000000000
--- a/src/testing/testing_api_cmd_netjail_start_testsystem_v2.c
+++ /dev/null
@@ -1,720 +0,0 @@
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_v2.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 * The complete topology information.
66 */
67 struct GNUNET_TESTING_NetjailTopology *topology;
68
69 /**
70 * Pointer to the return value of the test.
71 *
72 */
73 unsigned int *rv;
74
75 /**
76 * Head of the DLL which stores messages received by the helper.
77 *
78 */
79 struct HelperMessage *hp_messages_head;
80
81 /**
82 * Tail of the DLL which stores messages received by the helper.
83 *
84 */
85 struct HelperMessage *hp_messages_tail;
86
87 /**
88 * Array with handles of helper processes.
89 */
90 struct GNUNET_HELPER_Handle **helper;
91
92 /**
93 * Size of the array NetJailState#helper.
94 *
95 */
96 unsigned int n_helper;
97
98 /**
99 * Number of nodes in a natted subnet.
100 *
101 */
102 unsigned int local_m;
103
104 /**
105 * Number of natted subnets.
106 *
107 */
108 unsigned int global_n;
109
110 /**
111 * Number of global known nodes.
112 *
113 */
114 unsigned int known;
115
116 /**
117 * The send handle for the helper
118 */
119 struct GNUNET_HELPER_SendHandle **shandle;
120
121 /**
122 * Size of the array NetJailState#shandle.
123 *
124 */
125 unsigned int n_shandle;
126
127 /**
128 * The messages send to the helper.
129 */
130 struct GNUNET_MessageHeader **msg;
131
132 /**
133 * Size of the array NetJailState#msg.
134 *
135 */
136 unsigned int n_msg;
137
138 /**
139 * Number of test environments started.
140 *
141 */
142 unsigned int number_of_testsystems_started;
143
144 /**
145 * Number of peers started.
146 *
147 */
148 unsigned int number_of_peers_started;
149
150 /**
151 * Number of local tests finished.
152 *
153 */
154 unsigned int number_of_local_test_finished;
155
156 /**
157 * Name of the test case plugin the helper will load.
158 *
159 */
160 char *plugin_name;
161
162 /**
163 * HEAD of the DLL containing TestingSystemCount.
164 *
165 */
166 struct TestingSystemCount *tbcs_head;
167
168 /**
169 * TAIL of the DLL containing TestingSystemCount.
170 *
171 */
172 struct TestingSystemCount *tbcs_tail;
173};
174
175/**
176 * Struct containing the number of the test environment and the NetJailState which
177 * will be handed to callbacks specific to a test environment.
178 */
179struct TestingSystemCount
180{
181 /**
182 * Kept in a DLL.
183 */
184 struct TestingSystemCount *next;
185
186 /**
187 * Kept in a DLL.
188 */
189 struct TestingSystemCount *prev;
190
191 /**
192 * The number of the test environment.
193 *
194 */
195 unsigned int count;
196
197 /**
198 * Struct to store information handed over to callbacks.
199 *
200 */
201 struct NetJailState *ns;
202};
203
204/**
205* Code to clean up resource this cmd used.
206*
207* @param cls closure
208* @param cmd current CMD being cleaned up.
209*/
210static void
211netjail_exec_cleanup (void *cls,
212 const struct GNUNET_TESTING_Command *cmd)
213{
214 struct NetJailState *ns = cls;
215 struct HelperMessage *message_pos;
216 struct TestingSystemCount *tbc_pos;
217
218 while (NULL != (message_pos = ns->hp_messages_head))
219 {
220 GNUNET_CONTAINER_DLL_remove (ns->hp_messages_head,
221 ns->hp_messages_tail,
222 message_pos);
223 GNUNET_free (message_pos);
224 }
225 while (NULL != (tbc_pos = ns->tbcs_head))
226 {
227 GNUNET_CONTAINER_DLL_remove (ns->tbcs_head,
228 ns->tbcs_tail,
229 tbc_pos);
230 GNUNET_free (tbc_pos);
231 }
232 GNUNET_free (ns);
233}
234
235
236/**
237 * This function prepares an array with traits.
238 *
239 */
240static int
241netjail_exec_traits (void *cls,
242 const void **ret,
243 const char *trait,
244 unsigned int index)
245{
246 struct NetJailState *ns = cls;
247 struct GNUNET_HELPER_Handle **helper = ns->helper;
248 struct HelperMessage *hp_messages_head = ns->hp_messages_head;
249
250
251 struct GNUNET_TESTING_Trait traits[] = {
252 {
253 .index = 0,
254 .trait_name = "helper_handles",
255 .ptr = (const void *) helper,
256 },
257 {
258 .index = 1,
259 .trait_name = "hp_msgs_head",
260 .ptr = (const void *) hp_messages_head,
261 },
262 GNUNET_TESTING_trait_end ()
263 };
264
265 return GNUNET_TESTING_get_trait (traits,
266 ret,
267 trait,
268 index);
269}
270
271
272/**
273 * Offer handles to testing cmd helper from trait
274 *
275 * @param cmd command to extract the message from.
276 * @param pt pointer to message.
277 * @return #GNUNET_OK on success.
278 */
279int
280GNUNET_TESTING_get_trait_helper_handles_v2 (const struct
281 GNUNET_TESTING_Command *cmd,
282 struct GNUNET_HELPER_Handle ***
283 helper)
284{
285 return cmd->traits (cmd->cls,
286 (const void **) helper,
287 "helper_handles",
288 (unsigned int) 0);
289}
290
291
292/**
293 * Continuation function from GNUNET_HELPER_send()
294 *
295 * @param cls closure
296 * @param result GNUNET_OK on success,
297 * GNUNET_NO if helper process died
298 * GNUNET_SYSERR during GNUNET_HELPER_stop
299 */
300static void
301clear_msg (void *cls, int result)
302{
303 struct TestingSystemCount *tbc = cls;
304 struct NetJailState *ns = tbc->ns;
305
306 GNUNET_assert (NULL != ns->shandle[tbc->count - 1]);
307 ns->shandle[tbc->count - 1] = NULL;
308 GNUNET_free (ns->msg[tbc->count - 1]);
309 ns->msg[tbc->count - 1] = NULL;
310}
311
312
313/**
314 * Functions with this signature are called whenever a
315 * complete message is received by the tokenizer.
316 *
317 * Do not call GNUNET_SERVER_mst_destroy in callback
318 *
319 * @param cls closure
320 * @param client identification of the client
321 * @param message the actual message
322 *
323 * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
324 */
325static int
326helper_mst (void *cls, const struct GNUNET_MessageHeader *message)
327{
328 struct TestingSystemCount *tbc = cls;
329 struct NetJailState *ns = tbc->ns;
330 struct HelperMessage *hp_msg;
331
332 if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY == ntohs (message->type))
333 {
334 ns->number_of_testsystems_started++;
335 }
336 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED == ntohs (
337 message->type))
338 {
339 ns->number_of_peers_started++;
340 }
341 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED == ntohs (
342 message->type))
343 {
344 ns->number_of_local_test_finished++;
345 }
346 else
347 {
348 hp_msg = GNUNET_new (struct HelperMessage);
349 hp_msg->bytes_msg = message->size;
350 memcpy (&hp_msg[1], message, message->size);
351 GNUNET_CONTAINER_DLL_insert (ns->hp_messages_head, ns->hp_messages_tail,
352 hp_msg);
353 }
354
355 return GNUNET_OK;
356}
357
358
359/**
360 * Callback called if there was an exception during execution of the helper.
361 *
362 */
363static void
364exp_cb (void *cls)
365{
366 struct NetJailState *ns = cls;
367 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called exp_cb.\n");
368 *ns->rv = 1;
369}
370
371
372/**
373 * Function to initialize a init message for the helper.
374 *
375 * @param m_char The actual node in a namespace. //TODO Change this to unsigned int
376 * @param n_char The actual namespace. //TODO Change this to unsigned int
377 * @param plugin_name Name of the test case plugin the helper will load.
378 *
379 */
380static struct GNUNET_CMDS_HelperInit *
381create_helper_init_msg_ (const char *plugin_name)
382{
383 struct GNUNET_CMDS_HelperInit *msg;
384 uint16_t plugin_name_len;
385 uint16_t msg_size;
386
387 GNUNET_assert (NULL != plugin_name);
388 plugin_name_len = strlen (plugin_name);
389 msg_size = sizeof(struct GNUNET_CMDS_HelperInit) + plugin_name_len;
390 msg = GNUNET_malloc (msg_size);
391 msg->header.size = htons (msg_size);
392 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT);
393 msg->plugin_name_size = htons (plugin_name_len);
394 GNUNET_memcpy ((char *) &msg[1],
395 plugin_name,
396 plugin_name_len);
397 return msg;
398}
399
400
401/**
402 * Function which start a single helper process.
403 *
404 */
405static void
406start_helper (struct NetJailState *ns, struct
407 GNUNET_CONFIGURATION_Handle *config,
408 unsigned int m,
409 unsigned int n)
410{
411 struct GNUNET_HELPER_Handle *helper;
412 struct GNUNET_CMDS_HelperInit *msg;
413 struct TestingSystemCount *tbc;
414 char *m_char, *n_char, *global_n_char, *local_m_char, *known_char, *node_id,
415 *plugin;
416 pid_t pid;
417 unsigned int script_num;
418 struct GNUNET_ShortHashCode *hkey;
419 struct GNUNET_HashCode hc;
420 struct GNUNET_TESTING_NetjailTopology *topology = ns->topology;
421 struct GNUNET_TESTING_NetjailNode *node;
422 struct GNUNET_TESTING_NetjailNamespace *namespace;
423
424
425 if (0 == n)
426 script_num = m - 1;
427 else
428 script_num = n - 1 + (n - 1) * ns->local_m + m + ns->known;
429 pid = getpid ();
430
431 GNUNET_asprintf (&m_char, "%u", m);
432 GNUNET_asprintf (&n_char, "%u", n);
433 GNUNET_asprintf (&local_m_char, "%u", ns->local_m);
434 GNUNET_asprintf (&global_n_char, "%u",ns->global_n);
435 GNUNET_asprintf (&known_char, "%u",ns->known);
436 GNUNET_asprintf (&node_id, "%06x-%08x\n",
437 pid,
438 script_num);
439
440
441 char *const script_argv[] = {NETJAIL_EXEC_SCRIPT,
442 m_char,
443 n_char,
444 GNUNET_OS_get_libexec_binary_path (
445 HELPER_CMDS_BINARY),
446 global_n_char,
447 local_m_char,
448 node_id,
449 NULL};
450
451 unsigned int helper_check = GNUNET_OS_check_helper_binary (
452 NETJAIL_EXEC_SCRIPT,
453 GNUNET_YES,
454 NULL);
455
456 tbc = GNUNET_new (struct TestingSystemCount);
457 tbc->ns = ns;
458 if (0 == n)
459 tbc->count = m;
460 else
461 tbc->count = (n - 1) * ns->local_m + m + ns->known;
462
463 GNUNET_CONTAINER_DLL_insert (ns->tbcs_head, ns->tbcs_tail,
464 tbc);
465
466
467 if (GNUNET_NO == helper_check)
468 {
469 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
470 "No SUID for %s!\n",
471 NETJAIL_EXEC_SCRIPT);
472 *ns->rv = 1;
473 }
474 else if (GNUNET_NO == helper_check)
475 {
476 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
477 "%s not found!\n",
478 NETJAIL_EXEC_SCRIPT);
479 *ns->rv = 1;
480 }
481
482 GNUNET_array_append (ns->helper, ns->n_helper, GNUNET_HELPER_start (
483 GNUNET_YES,
484 NETJAIL_EXEC_SCRIPT,
485 script_argv,
486 &helper_mst,
487 &exp_cb,
488 tbc));
489
490 helper = ns->helper[tbc->count - 1];
491
492 hkey = GNUNET_new (struct GNUNET_ShortHashCode);
493
494 plugin = topology->plugin;
495
496 if (0 == m)
497 {
498
499 GNUNET_CRYPTO_hash (&n, sizeof(n), &hc);
500 memcpy (hkey,
501 &hc,
502 sizeof (*hkey));
503 if (1 == GNUNET_CONTAINER_multishortmap_contains (topology->map_globals,
504 hkey))
505 {
506 node = GNUNET_CONTAINER_multishortmap_get (topology->map_globals,
507 hkey);
508 if (NULL != node->plugin)
509 plugin = node->plugin;
510 }
511
512 }
513 else
514 {
515 GNUNET_CRYPTO_hash (&m, sizeof(m), &hc);
516 memcpy (hkey,
517 &hc,
518 sizeof (*hkey));
519 if (1 == GNUNET_CONTAINER_multishortmap_contains (topology->map_namespaces,
520 hkey))
521 {
522 namespace = GNUNET_CONTAINER_multishortmap_get (topology->map_namespaces,
523 hkey);
524 GNUNET_CRYPTO_hash (&n, sizeof(n), &hc);
525 memcpy (hkey,
526 &hc,
527 sizeof (*hkey));
528 if (1 == GNUNET_CONTAINER_multishortmap_contains (namespace->nodes,
529 hkey))
530 {
531 node = GNUNET_CONTAINER_multishortmap_get (namespace->nodes,
532 hkey);
533 if (NULL != node->plugin)
534 plugin = node->plugin;
535 }
536 }
537
538
539 }
540
541 msg = create_helper_init_msg_ (plugin);
542
543 GNUNET_array_append (ns->msg, ns->n_msg, &msg->header);
544
545 GNUNET_array_append (ns->shandle, ns->n_shandle, GNUNET_HELPER_send (
546 helper,
547 &msg->header,
548 GNUNET_NO,
549 &clear_msg,
550 tbc));
551
552 if (NULL == ns->shandle[tbc->count - 1])
553 {
554 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
555 "Send handle is NULL!\n");
556 GNUNET_free (msg);
557 *ns->rv = 1;
558 }
559}
560
561
562/**
563* This function starts a helper process for each node.
564*
565* @param cls closure.
566* @param cmd CMD being run.
567* @param is interpreter state.
568*/
569static void
570netjail_exec_run (void *cls,
571 const struct GNUNET_TESTING_Command *cmd,
572 struct GNUNET_TESTING_Interpreter *is)
573{
574 struct NetJailState *ns = cls;
575 struct GNUNET_CONFIGURATION_Handle *config =
576 GNUNET_CONFIGURATION_create ();
577
578 for (int i = 1; i <= ns->known; i++)
579 {
580 start_helper (ns, config,
581 i,
582 0);
583 }
584
585 for (int i = 1; i <= ns->global_n; i++)
586 {
587 for (int j = 1; j <= ns->local_m; j++)
588 {
589 start_helper (ns, config,
590 j,
591 i);
592 }
593 }
594}
595
596
597static void
598send_all_peers_started (unsigned int i, unsigned int j, struct NetJailState *ns)
599{
600 unsigned int total_number = ns->local_m * ns->global_n + ns->known;
601 struct GNUNET_CMDS_ALL_PEERS_STARTED *reply;
602 size_t msg_length;
603 struct GNUNET_HELPER_Handle *helper;
604 struct TestingSystemCount *tbc;
605
606 tbc = GNUNET_new (struct TestingSystemCount);
607 tbc->ns = ns;
608 // 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.
609 if (0 == i)
610 tbc->count = j + total_number;
611 else
612 tbc->count = (i - 1) * ns->local_m + j + total_number + ns->known;
613
614 helper = ns->helper[tbc->count - 1 - total_number];
615 msg_length = sizeof(struct GNUNET_CMDS_ALL_PEERS_STARTED);
616 reply = GNUNET_new (struct GNUNET_CMDS_ALL_PEERS_STARTED);
617 reply->header.type = htons (
618 GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED);
619 reply->header.size = htons ((uint16_t) msg_length);
620
621 GNUNET_array_append (ns->msg, ns->n_msg, &reply->header);
622
623 struct GNUNET_HELPER_SendHandle *sh = GNUNET_HELPER_send (
624 helper,
625 &reply->header,
626 GNUNET_NO,
627 &clear_msg,
628 tbc);
629
630 GNUNET_array_append (ns->shandle, ns->n_shandle, sh);
631}
632
633
634/**
635 * This function checks on three different information.
636 *
637 * 1. Did all helpers start. This is only logged.
638 * 2. Did all peer start.
639 * In this case a GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED is send to all peers.
640 * 3. Did all peers finished the test case. In this case interpreter_next will be called.
641 *
642 */
643static int
644netjail_start_finish (void *cls,
645 GNUNET_SCHEDULER_TaskCallback cont,
646 void *cont_cls)
647{
648 unsigned int ret = GNUNET_NO;
649 struct NetJailState *ns = cls;
650 unsigned int total_number = ns->local_m * ns->global_n + ns->known;
651
652
653 if (ns->number_of_local_test_finished == total_number)
654 {
655 ret = GNUNET_YES;
656 cont (cont_cls);
657 }
658
659 if (ns->number_of_testsystems_started == total_number)
660 {
661 ns->number_of_testsystems_started = 0;
662 }
663
664 if (ns->number_of_peers_started == total_number)
665 {
666 for (int i = 1; i <= ns->known; i++)
667 {
668 send_all_peers_started (0,i, ns);
669 }
670
671 for (int i = 1; i <= ns->global_n; i++)
672 {
673 for (int j = 1; j <= ns->local_m; j++)
674 {
675 send_all_peers_started (i,j, ns);
676 }
677 }
678 ns->number_of_peers_started = 0;
679 }
680 return ret;
681}
682
683
684/**
685 * Create command.
686 *
687 * @param label Name for the command.
688 * @param topology_config Configuration file for the test topology.
689 * @param rv Pointer to the return value of the test.
690 * @return command.
691 */
692struct GNUNET_TESTING_Command
693GNUNET_TESTING_cmd_netjail_start_testing_system_v2 (const char *label,
694 const char *topology_config,
695 unsigned int *rv)
696{
697 struct NetJailState *ns;
698
699 struct GNUNET_TESTING_NetjailTopology *topology =
700 GNUNET_TESTING_get_topo_from_file (topology_config);
701
702 ns = GNUNET_new (struct NetJailState);
703 ns->rv = rv;
704 ns->local_m = topology->nodes_m;
705 ns->global_n = topology->namespaces_n;
706 ns->known = topology->nodes_x;
707 ns->plugin_name = topology->plugin;
708 ns->topology = topology;
709
710 struct GNUNET_TESTING_Command cmd = {
711 .cls = ns,
712 .label = label,
713 .run = &netjail_exec_run,
714 .finish = &netjail_start_finish,
715 .cleanup = &netjail_exec_cleanup,
716 .traits = &netjail_exec_traits
717 };
718
719 return cmd;
720}
diff --git a/src/testing/testing_api_cmd_netjail_start_v2.c b/src/testing/testing_api_cmd_netjail_start_v2.c
deleted file mode 100644
index 9123148a7..000000000
--- a/src/testing/testing_api_cmd_netjail_start_v2.c
+++ /dev/null
@@ -1,249 +0,0 @@
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_v2.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 /**
42 * Configuration file for the test topology.
43 */
44 char *topology_config;
45
46 /**
47 * The process id of the start script.
48 */
49 struct GNUNET_OS_Process *start_proc;
50
51 // Flag indication if the script finished.
52 // FIXME: document 3 values
53 enum GNUNET_GenericReturnValue 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 // FIXME: log status code
121 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
122 "Child completed with an error!\n");
123 ns->finished = GNUNET_SYSERR;
124 }
125 GNUNET_OS_process_destroy (ns->start_proc);
126 ns->start_proc = NULL;
127}
128
129
130
131/**
132* The run method starts the script which setup the network namespaces.
133*
134* @param cls closure.
135* @param cmd CMD being run.
136* @param is interpreter state.
137*/
138static void
139netjail_start_run (void *cls,
140 const struct GNUNET_TESTING_Command *cmd,
141 struct GNUNET_TESTING_Interpreter *is)
142{
143 struct NetJailState *ns = cls;
144 char pid[15];
145 enum GNUNET_GenericReturnValue helper_check;
146
147 // FIXME: NETJAIL_START_SCRIPT like this is bad,
148 // use location from share/gnunet/ of installed
149 // binary in case libgnunettesting is used as a lib!
150 helper_check = GNUNET_OS_check_helper_binary (
151 NETJAIL_START_SCRIPT,
152 GNUNET_YES,
153 NULL);
154
155 if (GNUNET_NO == helper_check)
156 {
157 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
158 "No SUID for %s!\n",
159 NETJAIL_START_SCRIPT);
160 GNUNET_TESTING_interpreter_fail ();
161 return;
162 }
163 if (GNUNET_SYSERR == helper_check)
164 {
165 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
166 "%s not found!\n",
167 NETJAIL_START_SCRIPT);
168 GNUNET_TESTING_interpreter_fail ();
169 return;
170 }
171
172 GNUNET_snprintf (pid,
173 sizeof (pid),
174 "%u",
175 getpid ());
176 {
177 char *const script_argv[] = {
178 NETJAIL_START_SCRIPT,
179 ns->topology_config,
180 pid,
181 NULL
182 };
183
184 ns->start_proc
185 = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ERR,
186 NULL,
187 NULL,
188 NULL,
189 NETJAIL_START_SCRIPT,
190 script_argv);
191 }
192 ns->cwh = GNUNET_wait_child (ns->start_proc,
193 &child_completed_callback,
194 ns);
195 GNUNET_break (NULL != ns->cwh);
196}
197
198
199/**
200 * This function checks the flag NetJailState
201 *
202 * FIXME: fix comment!
203 * #finished, if this cmd finished.
204 *
205 */
206static enum GNUNET_GenericReturnValue
207netjail_start_finish (void *cls,
208 GNUNET_SCHEDULER_TaskCallback cont,
209 void *cont_cls)
210{
211 struct NetJailState *ns = cls;
212
213 if (GNUNET_NO != ns->finished)
214 {
215 cont (cont_cls);
216 }
217 // FIXME: cont should be called later in the else case!
218 return ns->finished;
219}
220
221
222/**
223 * Create command.
224 *
225 * @param label name for command.
226 * @param topology_config Configuration file for the test topology.
227 * @return command.
228 */
229struct GNUNET_TESTING_Command
230GNUNET_TESTING_cmd_netjail_start_v2 (const char *label,
231 char *topology_config)
232{
233 struct NetJailState *ns;
234
235 ns = GNUNET_new (struct NetJailState);
236 ns->topology_config = topology_config;
237 {
238 struct GNUNET_TESTING_Command cmd = {
239 .cls = ns,
240 .label = label,
241 .run = &netjail_start_run,
242 .finish = &netjail_start_finish,
243 .cleanup = &netjail_start_cleanup,
244 .traits = &netjail_start_traits
245 };
246
247 return cmd;
248 }
249}
diff --git a/src/testing/testing_api_cmd_netjail_stop.c b/src/testing/testing_api_cmd_netjail_stop.c
deleted file mode 100644
index 99084d9af..000000000
--- a/src/testing/testing_api_cmd_netjail_stop.c
+++ /dev/null
@@ -1,225 +0,0 @@
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
deleted file mode 100644
index 0ae82a26a..000000000
--- a/src/testing/testing_api_cmd_netjail_stop_testsystem.c
+++ /dev/null
@@ -1,143 +0,0 @@
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_netjail_stop_testsystem_v2.c b/src/testing/testing_api_cmd_netjail_stop_testsystem_v2.c
deleted file mode 100644
index 8eccc5764..000000000
--- a/src/testing/testing_api_cmd_netjail_stop_testsystem_v2.c
+++ /dev/null
@@ -1,143 +0,0 @@
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 unsigned int local_m;
46
47 unsigned int 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 <= shs->global_n; i++)
101 {
102 for (int j = 1; j <= shs->local_m; j++)
103 {
104 GNUNET_HELPER_stop (helper[(i - 1) * 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 helper_start_label label of the cmd to start the test system.
116 * @param topology_config Configuration file for the test topology.
117 * @return command.
118 */
119struct GNUNET_TESTING_Command
120GNUNET_TESTING_cmd_stop_testing_system_v2 (const char *label,
121 const char *helper_start_label,
122 const char *topology_config)
123{
124 struct StopHelperState *shs;
125
126 struct GNUNET_TESTING_NetjailTopology *topology =
127 GNUNET_TESTING_get_topo_from_file (topology_config);
128
129 shs = GNUNET_new (struct StopHelperState);
130 shs->helper_start_label = helper_start_label;
131 shs->local_m = topology->nodes_m;
132 shs->global_n = topology->namespaces_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_netjail_stop_v2.c b/src/testing/testing_api_cmd_netjail_stop_v2.c
deleted file mode 100644
index 8c1f3cedd..000000000
--- a/src/testing/testing_api_cmd_netjail_stop_v2.c
+++ /dev/null
@@ -1,225 +0,0 @@
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_v2.sh"
32
33// Child Wait handle
34static struct GNUNET_ChildWaitHandle *cwh;
35
36/**
37 * Struct to hold information for callbacks.
38 *
39 */
40struct NetJailState
41{
42 /**
43 * Configuration file for the test topology.
44 */
45 char *topology_config;
46
47 /**
48 * The process id of the start script.
49 */
50 struct GNUNET_OS_Process *stop_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_stop_cleanup (void *cls,
63 const struct GNUNET_TESTING_Command *cmd)
64{
65 struct NetJailState *ns = cls;
66
67 if (NULL != cwh)
68 {
69 GNUNET_wait_child_cancel (cwh);
70 cwh = NULL;
71 }
72 if (NULL != ns->stop_proc)
73 {
74 GNUNET_assert (0 ==
75 GNUNET_OS_process_kill (ns->stop_proc,
76 SIGKILL));
77 GNUNET_assert (GNUNET_OK ==
78 GNUNET_OS_process_wait (ns->stop_proc));
79 GNUNET_OS_process_destroy (ns->stop_proc);
80 ns->stop_proc = NULL;
81 }
82}
83
84
85/**
86 * Trait function of this cmd does nothing.
87 *
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
99/**
100 * Callback which will be called if the setup script finished.
101 *
102 */
103static void
104child_completed_callback (void *cls,
105 enum GNUNET_OS_ProcessStatusType type,
106 long unsigned int exit_code)
107{
108 struct NetJailState *ns = cls;
109
110 cwh = NULL;
111 if (0 == exit_code)
112 {
113 ns->finished = GNUNET_YES;
114 }
115 else
116 {
117 ns->finished = GNUNET_SYSERR;
118 }
119 GNUNET_OS_process_destroy (ns->stop_proc);
120 ns->stop_proc = NULL;
121}
122
123
124/**
125* The run method starts the script which deletes the network namespaces.
126*
127* @param cls closure.
128* @param cmd CMD being run.
129* @param is interpreter state.
130*/
131static void
132netjail_stop_run (void *cls,
133 const struct GNUNET_TESTING_Command *cmd,
134 struct GNUNET_TESTING_Interpreter *is)
135{
136 struct NetJailState *ns = cls;
137 char *pid;
138 GNUNET_asprintf (&pid,
139 "%u",
140 getpid ());
141 char *const script_argv[] = {NETJAIL_STOP_SCRIPT,
142 ns->topology_config,
143 pid,
144 NULL};
145 unsigned int helper_check = GNUNET_OS_check_helper_binary (
146 NETJAIL_STOP_SCRIPT,
147 GNUNET_YES,
148 NULL);
149
150 if (GNUNET_NO == helper_check)
151 {
152 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
153 "No SUID for %s!\n",
154 NETJAIL_STOP_SCRIPT);
155 GNUNET_TESTING_interpreter_fail ();
156 }
157 else if (GNUNET_NO == helper_check)
158 {
159 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
160 "%s not found!\n",
161 NETJAIL_STOP_SCRIPT);
162 GNUNET_TESTING_interpreter_fail ();
163 }
164
165 ns->stop_proc = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ERR,
166 NULL,
167 NULL,
168 NULL,
169 NETJAIL_STOP_SCRIPT,
170 script_argv);
171
172 cwh = GNUNET_wait_child (ns->stop_proc,
173 &child_completed_callback,
174 ns);
175 GNUNET_break (NULL != cwh);
176
177}
178
179
180/**
181 * This function checks the flag NetJailState#finished, if this cmd finished.
182 *
183 */
184static int
185netjail_stop_finish (void *cls,
186 GNUNET_SCHEDULER_TaskCallback cont,
187 void *cont_cls)
188{
189 struct NetJailState *ns = cls;
190
191 if (ns->finished)
192 {
193 cont (cont_cls);
194 }
195 return ns->finished;
196}
197
198
199/**
200 * Create command.
201 *
202 * @param label name for command.
203 * @param topology_config Configuration file for the test topology.
204 * @return command.
205 */
206struct GNUNET_TESTING_Command
207GNUNET_TESTING_cmd_netjail_stop_v2 (const char *label,
208 char *topology_config)
209{
210 struct NetJailState *ns;
211
212 ns = GNUNET_new (struct NetJailState);
213 ns->topology_config = topology_config;
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_send_peer_ready.c b/src/testing/testing_api_cmd_send_peer_ready.c
deleted file mode 100644
index 016837214..000000000
--- a/src/testing/testing_api_cmd_send_peer_ready.c
+++ /dev/null
@@ -1,128 +0,0 @@
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_send_peer_ready.c
23 * @brief cmd to send a helper message if peer is ready.
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/**
33 * Struct to hold information for callbacks.
34 *
35 */
36struct SendPeerReadyState
37{
38 /**
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 */
48 struct GNUNET_CMDS_PEER_STARTED *reply;
49};
50
51
52/**
53 * Trait function of this cmd does nothing.
54 *
55 */
56static int
57send_peer_ready_traits (void *cls,
58 const void **ret,
59 const char *trait,
60 unsigned int index)
61{
62 return GNUNET_OK;
63}
64
65
66/**
67 * The cleanup function of this cmd frees resources the cmd allocated.
68 *
69 */
70static void
71send_peer_ready_cleanup (void *cls,
72 const struct GNUNET_TESTING_Command *cmd)
73{
74 struct SendPeerReadyState *sprs = cls;
75
76 GNUNET_free (sprs->reply);
77 GNUNET_free (sprs);
78}
79
80
81/**
82 * This function sends a GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED message to the master loop.
83 *
84 */
85static void
86send_peer_ready_run (void *cls,
87 const struct GNUNET_TESTING_Command *cmd,
88 struct GNUNET_TESTING_Interpreter *is)
89{
90 struct SendPeerReadyState *sprs = cls;
91 struct GNUNET_CMDS_PEER_STARTED *reply;
92 size_t msg_length;
93
94 msg_length = sizeof(struct GNUNET_CMDS_PEER_STARTED);
95 reply = GNUNET_new (struct GNUNET_CMDS_PEER_STARTED);
96 reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED);
97 reply->header.size = htons ((uint16_t) msg_length);
98 sprs->reply = reply;
99 sprs->write_message ((struct GNUNET_MessageHeader *) reply, msg_length);
100}
101
102
103/**
104 * Create command.
105 *
106 * @param label name for command.
107 * @param write_message Callback to write messages to the master loop.
108 * @return command.
109 */
110struct GNUNET_TESTING_Command
111GNUNET_TESTING_cmd_send_peer_ready (const char *label,
112 TESTING_CMD_HELPER_write_cb write_message)
113{
114 struct SendPeerReadyState *sprs;
115
116 sprs = GNUNET_new (struct SendPeerReadyState);
117 sprs->write_message = write_message;
118
119 struct GNUNET_TESTING_Command cmd = {
120 .cls = sprs,
121 .label = label,
122 .run = &send_peer_ready_run,
123 .cleanup = &send_peer_ready_cleanup,
124 .traits = &send_peer_ready_traits
125 };
126
127 return cmd;
128}
diff --git a/src/testing/testing_api_cmd_system_create.c b/src/testing/testing_api_cmd_system_create.c
deleted file mode 100644
index f3a0b1a4c..000000000
--- a/src/testing/testing_api_cmd_system_create.c
+++ /dev/null
@@ -1,152 +0,0 @@
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_create.c
23 * @brief cmd to create 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 * Struct to hold information for callbacks.
33 *
34 */
35struct TestSystemState
36{
37 struct GNUNET_TESTING_System *test_system;
38
39 const char *testdir;
40};
41
42
43/**
44 * The run method of this cmd will setup a test environment for a node.
45 *
46 */
47static void
48system_create_run (void *cls,
49 const struct GNUNET_TESTING_Command *cmd,
50 struct GNUNET_TESTING_Interpreter *is)
51{
52 struct TestSystemState *tss = cls;
53
54 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
55 "system create\n");
56
57 tss->test_system = GNUNET_TESTING_system_create (tss->testdir,
58 NULL,
59 NULL,
60 NULL);
61 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
62 "system created\n");
63}
64
65
66/**
67 * This function prepares an array with traits.
68 *
69 */
70static int
71system_create_traits (void *cls,
72 const void **ret,
73 const char *trait,
74 unsigned int index)
75{
76 struct TestSystemState *tss = cls;
77 struct GNUNET_TESTING_System *test_system = tss->test_system;
78
79 struct GNUNET_TESTING_Trait traits[] = {
80 {
81 .index = 0,
82 .trait_name = "test_system",
83 .ptr = (const void *) test_system,
84 },
85 GNUNET_TESTING_trait_end ()
86 };
87
88 return GNUNET_TESTING_get_trait (traits,
89 ret,
90 trait,
91 index);
92}
93
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 */
101int
102GNUNET_TESTING_get_trait_test_system (const struct
103 GNUNET_TESTING_Command *cmd,
104 struct GNUNET_TESTING_System **test_system)
105{
106 return cmd->traits (cmd->cls,
107 (const void **) test_system,
108 "test_system",
109 (unsigned int) 0);
110}
111
112
113/**
114 * The cleanup function of this cmd frees resources the cmd allocated.
115 *
116 */
117static void
118system_create_cleanup (void *cls,
119 const struct GNUNET_TESTING_Command *cmd)
120{
121 struct TestSystemState *tss = cls;
122
123 GNUNET_free (tss);
124}
125
126
127/**
128 * Create command.
129 *
130 * @param label name for command.
131 * @param label name for the test environment directory.
132 * @return command.
133 */
134struct GNUNET_TESTING_Command
135GNUNET_TESTING_cmd_system_create (const char *label,
136 const char *testdir)
137{
138 struct TestSystemState *tss;
139
140 tss = GNUNET_new (struct TestSystemState);
141 tss->testdir = testdir;
142
143 struct GNUNET_TESTING_Command cmd = {
144 .cls = tss,
145 .label = label,
146 .run = &system_create_run,
147 .cleanup = &system_create_cleanup,
148 .traits = &system_create_traits
149 };
150
151 return cmd;
152}
diff --git a/src/testing/testing_api_cmd_system_destroy.c b/src/testing/testing_api_cmd_system_destroy.c
deleted file mode 100644
index 5ed0c2fd2..000000000
--- a/src/testing/testing_api_cmd_system_destroy.c
+++ /dev/null
@@ -1,116 +0,0 @@
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
deleted file mode 100644
index 0c24c0e26..000000000
--- a/src/testing/testing_api_loop.c
+++ /dev/null
@@ -1,599 +0,0 @@
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_loop.c
23 * @brief main interpreter loop for testcases
24 * @author Christian Grothoff (GNU Taler testing)
25 * @author Marcello Stanisci (GNU Taler testing)
26 * @author t3sserakt
27*/
28#include "platform.h"
29#include "gnunet_util_lib.h"
30#include "gnunet_testing_ng_lib.h"
31#include "testing.h"
32
33#define CHECK_FINISHED_PERIOD \
34 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
35
36struct GNUNET_TESTING_Interpreter *is;
37
38
39/**
40 * Closure used to sync an asynchronous with an synchronous command.
41 */
42struct SyncTaskClosure
43{
44
45 /**
46 * The asynchronous command the synchronous command waits for.
47 */
48 const struct GNUNET_TESTING_Command *async_cmd;
49
50 /**
51 * The synchronous command that waits for the asynchronous command.
52 */
53 const struct GNUNET_TESTING_Command *sync_cmd;
54
55 /**
56 * The interpreter of the test.
57 */
58 struct GNUNET_TESTING_Interpreter *is;
59};
60
61
62/**
63* Closure used to run the finish task.
64*/
65struct FinishTaskClosure
66{
67
68 /**
69 * The asynchronous command the synchronous command waits for.
70 */
71 const struct GNUNET_TESTING_Command *cmd;
72
73 /**
74 * The interpreter of the test.
75 */
76 struct GNUNET_TESTING_Interpreter *is;
77};
78
79
80/**
81 * Lookup command by label.
82 *
83 * @param label label to look for
84 * @return NULL if command was not found
85 */
86const struct GNUNET_TESTING_Command *
87GNUNET_TESTING_interpreter_lookup_command (const char *label)
88{
89 if (NULL == label)
90 {
91 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
92 "Attempt to lookup command for empty label\n");
93 return NULL;
94 }
95 /* Search backwards as we most likely reference recent commands */
96 for (int i = is->ip; i >= 0; i--)
97 {
98 const struct GNUNET_TESTING_Command *cmd = &is->commands[i];
99
100 /* Give precedence to top-level commands. */
101 if ( (NULL != cmd->label) &&
102 (0 == strcmp (cmd->label,
103 label)) )
104 return cmd;
105
106 if (GNUNET_TESTING_cmd_is_batch (cmd))
107 {
108#define BATCH_INDEX 1
109 struct GNUNET_TESTING_Command *batch;
110 struct GNUNET_TESTING_Command *current;
111 struct GNUNET_TESTING_Command *icmd;
112 const struct GNUNET_TESTING_Command *match;
113
114 current = GNUNET_TESTING_cmd_batch_get_current (cmd);
115 GNUNET_assert (GNUNET_OK ==
116 GNUNET_TESTING_get_trait_cmd (cmd,
117 BATCH_INDEX,
118 &batch));
119 /* We must do the loop forward, but we can find the last match */
120 match = NULL;
121 for (unsigned int j = 0;
122 NULL != (icmd = &batch[j])->label;
123 j++)
124 {
125 if (current == icmd)
126 break; /* do not go past current command */
127 if ( (NULL != icmd->label) &&
128 (0 == strcmp (icmd->label,
129 label)) )
130 match = icmd;
131 }
132 if (NULL != match)
133 return match;
134 }
135 }
136 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
137 "Command not found: %s\n",
138 label);
139 return NULL;
140
141}
142
143
144/**
145 * Run the main interpreter loop that performs exchange operations.
146 *
147 * @param cls contains the `struct InterpreterState`
148 */
149static void
150interpreter_run (void *cls);
151
152
153/**
154 * Current command is done, run the next one.
155 */
156static void
157interpreter_next (void *cls)
158{
159 struct GNUNET_TESTING_Interpreter *is = cls;
160 static unsigned long long ipc;
161 static struct GNUNET_TIME_Absolute last_report;
162 struct GNUNET_TESTING_Command *cmd = &is->commands[is->ip];
163
164 if (GNUNET_SYSERR == is->result)
165 return; /* ignore, we already failed! */
166 if (GNUNET_TESTING_cmd_is_batch (cmd))
167 {
168 GNUNET_TESTING_cmd_batch_next (is);
169 }
170 else
171 {
172 cmd->finish_time = GNUNET_TIME_absolute_get ();
173 is->ip++;
174 }
175 if (0 == (ipc % 1000))
176 {
177 if (0 != ipc)
178 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
179 "Interpreter executed 1000 instructions in %s\n",
180 GNUNET_STRINGS_relative_time_to_string (
181 GNUNET_TIME_absolute_get_duration (last_report),
182 GNUNET_YES));
183 last_report = GNUNET_TIME_absolute_get ();
184 }
185 ipc++;
186 is->task = GNUNET_SCHEDULER_add_now (&interpreter_run,
187 is);
188}
189
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 */
195static void
196run_finish_task_next (void *cls)
197{
198 struct FinishTaskClosure *ftc = cls;
199 const struct GNUNET_TESTING_Command *cmd = ftc->cmd;
200 struct GNUNET_TESTING_Interpreter *is = ftc->is;
201 unsigned int finished = cmd->finish (cmd->cls, &interpreter_next, is);
202
203 if (GNUNET_YES == finished)
204 {
205 is->finish_task = NULL;
206 }
207 else if (GNUNET_NO == finished)
208 {
209 is->finish_task = GNUNET_SCHEDULER_add_delayed (CHECK_FINISHED_PERIOD,
210 &run_finish_task_next, ftc);
211 }
212 else
213 {
214 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
215 "Next task finished with an error.\n");
216 GNUNET_TESTING_interpreter_fail ();
217 }
218
219}
220
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 */
228static void
229run_finish_task_sync (void *cls)
230{
231 struct SyncTaskClosure *stc = cls;
232 const struct GNUNET_TESTING_Command *cmd = stc->async_cmd;
233 const struct GNUNET_TESTING_Command *sync_cmd = stc->sync_cmd;
234 struct FinishTaskClosure *ftc;
235 struct SyncState *sync_state = sync_cmd->cls;
236 struct GNUNET_SCHEDULER_Task *finish_task = sync_state->finish_task;
237 unsigned int finished = cmd->finish (cmd->cls, &interpreter_next, is);
238
239 GNUNET_assert (NULL != finish_task);
240 ftc = GNUNET_new (struct FinishTaskClosure);
241 ftc->cmd = stc->sync_cmd;
242 ftc->is = stc->is;
243 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
244 if (cmd->default_timeout.rel_value_us < now.abs_value_us
245 - sync_state->start_finish_time.abs_value_us)
246 {
247 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
248 "The command with label %s did not finish its asynchronous task in time.\n",
249 cmd->label);
250 GNUNET_TESTING_interpreter_fail ();
251 }
252
253 if (GNUNET_YES == finished)
254 {
255 finish_task = NULL;
256 }
257 else if (GNUNET_NO == finished)
258 {
259 finish_task = GNUNET_SCHEDULER_add_delayed (CHECK_FINISHED_PERIOD,
260 &run_finish_task_sync, stc);
261 }
262 else
263 {
264 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
265 "Sync task finished with an error.\n");
266 GNUNET_TESTING_interpreter_fail ();
267 }
268}
269
270
271/**
272 * run method of the command created by the interpreter to wait for another command to finish.
273 *
274 */
275static void
276start_finish_on_ref (void *cls,
277 const struct GNUNET_TESTING_Command *cmd,
278 struct GNUNET_TESTING_Interpreter *is)
279{
280 struct SyncState *sync_state = cls;
281 struct SyncTaskClosure *stc;
282 const struct GNUNET_TESTING_Command *async_cmd;
283
284 async_cmd = sync_state->async_cmd;
285 stc = GNUNET_new (struct SyncTaskClosure);
286 stc->async_cmd = async_cmd;
287 stc->sync_cmd = cmd;
288 stc->is = is;
289 sync_state->start_finish_time = GNUNET_TIME_absolute_get ();
290 sync_state->finish_task = GNUNET_SCHEDULER_add_delayed (
291 CHECK_FINISHED_PERIOD,
292 &run_finish_task_sync,
293 stc);
294}
295
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 */
308const struct GNUNET_TESTING_Command
309GNUNET_TESTING_cmd_finish (const char *finish_label,
310 const char *cmd_ref,
311 struct GNUNET_TIME_Relative timeout)
312{
313 const struct GNUNET_TESTING_Command *async_cmd;
314 struct SyncState *sync_state;
315
316 async_cmd = GNUNET_TESTING_interpreter_lookup_command (cmd_ref);
317 sync_state = GNUNET_new (struct SyncState);
318 sync_state->async_cmd = async_cmd;
319
320 struct GNUNET_TESTING_Command cmd = {
321 .cls = sync_state,
322 .label = finish_label,
323 .run = &start_finish_on_ref,
324 .asynchronous_finish = GNUNET_NO
325 };
326
327 return cmd;
328}
329
330
331const struct GNUNET_TESTING_Command
332GNUNET_TESTING_cmd_make_unblocking (const struct GNUNET_TESTING_Command cmd)
333{
334
335 GNUNET_assert (NULL != cmd.finish);
336 const struct GNUNET_TESTING_Command async_cmd = {
337 .cls = cmd.cls,
338 .label = cmd.label,
339 .run = cmd.run,
340 .cleanup = cmd.cleanup,
341 .traits = cmd.traits,
342 .finish = cmd.finish,
343 .asynchronous_finish = GNUNET_YES
344 };
345
346 return async_cmd;
347}
348
349
350/**
351 * Current command failed, clean up and fail the test case.
352 *
353 * @param is interpreter of the test
354 */
355void
356GNUNET_TESTING_interpreter_fail ()
357{
358 struct GNUNET_TESTING_Command *cmd = &is->commands[is->ip];
359
360 if (GNUNET_SYSERR == is->result)
361 return; /* ignore, we already failed! */
362
363 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
364 "interpreter_fail!\n");
365
366 if (NULL != cmd)
367 {
368 while (GNUNET_TESTING_cmd_is_batch (cmd))
369 {
370 cmd = GNUNET_TESTING_cmd_batch_get_current (cmd);
371 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
372 "Batch is at command `%s'\n",
373 cmd->label);
374 }
375
376 }
377 else
378 {
379 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
380 "cmd is NULL.\n");
381 }
382
383 if (NULL == cmd->label)
384 {
385 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
386 "Failed at command `%s'\n",
387 cmd->label);
388
389 }
390 else
391 {
392 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
393 "cmd->label is NULL.\n");
394 }
395
396 is->result = GNUNET_SYSERR;
397 GNUNET_SCHEDULER_shutdown ();
398}
399
400
401/**
402 * Create command array terminator.
403 *
404 * @return a end-command.
405 */
406struct GNUNET_TESTING_Command
407GNUNET_TESTING_cmd_end (void)
408{
409 static struct GNUNET_TESTING_Command cmd;
410 cmd.label = NULL;
411
412 return cmd;
413}
414
415
416/**
417 * Obtain current label.
418 */
419const char *
420GNUNET_TESTING_interpreter_get_current_label (struct
421 GNUNET_TESTING_Interpreter *is)
422{
423 struct GNUNET_TESTING_Command *cmd = &is->commands[is->ip];
424
425 return cmd->label;
426}
427
428
429/**
430 * Run the main interpreter loop.
431 *
432 * @param cls contains the `struct GNUNET_TESTING_Interpreter`
433 */
434static void
435interpreter_run (void *cls)
436{
437 struct FinishTaskClosure *ftc;
438 struct GNUNET_TESTING_Interpreter *is = cls;
439 struct GNUNET_TESTING_Command *cmd = &is->commands[is->ip];
440
441 is->task = NULL;
442
443 if (NULL == cmd->label)
444 {
445
446 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
447 "Running command END %p\n",
448 is);
449 is->result = GNUNET_OK;
450 GNUNET_SCHEDULER_shutdown ();
451 return;
452 }
453 else if (NULL != cmd)
454 {
455 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
456 "Running command `%s' %p\n",
457 cmd->label,
458 is);
459 }
460 cmd->start_time
461 = cmd->last_req_time
462 = GNUNET_TIME_absolute_get ();
463 cmd->num_tries = 1;
464 cmd->run (cmd->cls,
465 cmd,
466 is);
467 if ((NULL != cmd->finish) && (GNUNET_NO == cmd->asynchronous_finish))
468 {
469 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
470 "Next task will not be called directly!\n");
471 ftc = GNUNET_new (struct FinishTaskClosure);
472 ftc->cmd = cmd;
473 ftc->is = is;
474 is->finish_task = GNUNET_SCHEDULER_add_delayed (CHECK_FINISHED_PERIOD,
475 &run_finish_task_next,
476 ftc);
477 }
478 else
479 {
480 interpreter_next (is);
481 }
482}
483
484
485/**
486 * Function run when the test terminates (good or bad).
487 * Cleans up our state.
488 *
489 * @param cls the interpreter state.
490 */
491static void
492do_shutdown (void *cls)
493{
494 (void) cls;
495 struct GNUNET_TESTING_Command *cmd;
496 const char *label;
497
498 label = is->commands[is->ip].label;
499 if (NULL == label)
500 label = "END";
501
502 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
503 "Executing shutdown at `%s'\n",
504 label);
505
506 for (unsigned int j = 0;
507 NULL != (cmd = &is->commands[j])->label;
508 j++) {
509 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
510 "Cleaning up cmd %s\n",
511 cmd->label);
512 cmd->cleanup (cmd->cls,
513 cmd);
514 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
515 "Cleaned up cmd %s\n",
516 cmd->label);
517 }
518
519 if (NULL != is->finish_task)
520 {
521 GNUNET_SCHEDULER_cancel (is->finish_task);
522 cmd->finish_task = NULL;
523 }
524
525 if (NULL != is->task)
526 {
527 GNUNET_SCHEDULER_cancel (is->task);
528 is->task = NULL;
529 }
530 if (NULL != is->timeout_task)
531 {
532 GNUNET_SCHEDULER_cancel (is->timeout_task);
533 is->timeout_task = NULL;
534 }
535 GNUNET_free (is->commands);
536}
537
538
539/**
540 * Function run when the test terminates (good or bad) with timeout.
541 *
542 * @param cls NULL
543 */
544static void
545do_timeout (void *cls)
546{
547 (void) cls;
548
549 is->timeout_task = NULL;
550 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
551 "Terminating test due to timeout\n");
552 GNUNET_SCHEDULER_shutdown ();
553}
554
555
556/**
557 * Run the testsuite. Note, CMDs are copied into
558 * the interpreter state because they are _usually_
559 * defined into the "run" method that returns after
560 * having scheduled the test interpreter.
561 *
562 * @param is the interpreter state
563 * @param commands the list of command to execute
564 * @param timeout how long to wait
565 */
566int
567GNUNET_TESTING_run (const char *cfg_filename,
568 struct GNUNET_TESTING_Command *commands,
569 struct GNUNET_TIME_Relative timeout)
570{
571 unsigned int i;
572
573 is = GNUNET_new (struct GNUNET_TESTING_Interpreter);
574
575 if (NULL != is->timeout_task)
576 {
577 GNUNET_SCHEDULER_cancel (is->timeout_task);
578 is->timeout_task = NULL;
579 }
580 /* get the number of commands */
581 for (i = 0; NULL != commands[i].label; i++)
582 ;
583 is->commands = GNUNET_new_array (i + 1,
584 struct GNUNET_TESTING_Command);
585 memcpy (is->commands,
586 commands,
587 sizeof (struct GNUNET_TESTING_Command) * i);
588
589 is->timeout_task = GNUNET_SCHEDULER_add_delayed
590 (timeout,
591 &do_timeout,
592 is);
593 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, is);
594 is->task = GNUNET_SCHEDULER_add_now (&interpreter_run, is);
595 return GNUNET_OK;
596}
597
598
599/* end of testing_api_loop.c */
diff --git a/src/testing/testing_api_trait_cmd.c b/src/testing/testing_api_trait_cmd.c
deleted file mode 100644
index 886baee5b..000000000
--- a/src/testing/testing_api_trait_cmd.c
+++ /dev/null
@@ -1,79 +0,0 @@
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_trait_cmd.c
23 * @brief offers CMDs as traits.
24 * @author Marcello Stanisci (GNU Taler testing)
25 * @author t3sserakt
26 */
27#include "platform.h"
28#include "gnunet_testing_ng_lib.h"
29
30#define GNUNET_TESTING_TRAIT_CMD "cmd"
31
32
33/**
34 * Obtain a command from @a cmd.
35 *
36 * @param cmd command to extract the command from.
37 * @param index always zero. Commands offering this
38 * kind of traits do not need this index. For
39 * example, a "batch" CMD returns always the
40 * CMD currently being executed.
41 * @param[out] _cmd where to write the wire details.
42 * @return #GNUNET_OK on success.
43 */
44int
45GNUNET_TESTING_get_trait_cmd (const struct GNUNET_TESTING_Command *cmd,
46 unsigned int index,
47 struct GNUNET_TESTING_Command **_cmd)
48{
49 return cmd->traits (cmd->cls,
50 (const void **) _cmd,
51 GNUNET_TESTING_TRAIT_CMD,
52 index);
53}
54
55
56/**
57 * Offer a command in a trait.
58 *
59 * @param index always zero. Commands offering this
60 * kind of traits do not need this index. For
61 * example, a "meta" CMD returns always the
62 * CMD currently being executed.
63 * @param cmd wire details to offer.
64 * @return the trait.
65 */
66struct GNUNET_TESTING_Trait
67GNUNET_TESTING_make_trait_cmd (unsigned int index,
68 const struct GNUNET_TESTING_Command *cmd)
69{
70 struct GNUNET_TESTING_Trait ret = {
71 .index = index,
72 .trait_name = GNUNET_TESTING_TRAIT_CMD,
73 .ptr = (const struct GNUNET_TESTING_Command *) cmd
74 };
75 return ret;
76}
77
78
79/* end of testing_api_trait_cmd.c */
diff --git a/src/testing/testing_api_trait_process.c b/src/testing/testing_api_trait_process.c
deleted file mode 100644
index 31cdb01df..000000000
--- a/src/testing/testing_api_trait_process.c
+++ /dev/null
@@ -1,81 +0,0 @@
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_trait_process.c
23 * @brief trait offering process handles.
24 * @author Christian Grothoff (GNU Taler testing)
25 * @author Marcello Stanisci (GNU Taler testing)
26 * @author t3sserakt
27 */
28#include "platform.h"
29#include "gnunet_testing_ng_lib.h"
30
31#define GNUNET_TESTING_TRAIT_PROCESS "process"
32
33
34/**
35 * Obtain location where a command stores a pointer to a process.
36 *
37 * @param cmd command to extract trait from.
38 * @param index which process to pick if @a cmd
39 * has multiple on offer.
40 * @param[out] processp set to the address of the pointer to the
41 * process.
42 * @return #GNUNET_OK on success.
43 */
44int
45GNUNET_TESTING_get_trait_process
46 (const struct GNUNET_TESTING_Command *cmd,
47 unsigned int index,
48 struct GNUNET_OS_Process ***processp)
49{
50 return cmd->traits (cmd->cls,
51 (const void **) processp,
52 GNUNET_TESTING_TRAIT_PROCESS,
53 index);
54}
55
56
57/**
58 * Offer location where a command stores a pointer to a process.
59 *
60 * @param index offered location index number, in case there are
61 * multiple on offer.
62 * @param processp process location to offer.
63 *
64 * @return the trait.
65 */
66struct GNUNET_TESTING_Trait
67GNUNET_TESTING_make_trait_process
68 (unsigned int index,
69 struct GNUNET_OS_Process **processp)
70{
71 struct GNUNET_TESTING_Trait ret = {
72 .index = index,
73 .trait_name = GNUNET_TESTING_TRAIT_PROCESS,
74 .ptr = (const void *) processp
75 };
76
77 return ret;
78}
79
80
81/* end of testing_api_trait_process.c */
diff --git a/src/testing/testing_api_traits.c b/src/testing/testing_api_traits.c
deleted file mode 100644
index 66626833d..000000000
--- a/src/testing/testing_api_traits.c
+++ /dev/null
@@ -1,81 +0,0 @@
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_traits.c
23 * @brief loop for trait resolution
24 * @author Christian Grothoff (GNU Taler testing)
25 * @author Marcello Stanisci (GNU Taler testing)
26 * @author t3sserakt
27 */
28#include "platform.h"
29#include "gnunet_testing_ng_lib.h"
30
31
32/**
33 * End a trait array. Usually, commands offer several traits,
34 * and put them in arrays.
35 */
36struct GNUNET_TESTING_Trait
37GNUNET_TESTING_trait_end ()
38{
39 struct GNUNET_TESTING_Trait end = {
40 .index = 0,
41 .trait_name = NULL,
42 .ptr = NULL
43 };
44
45 return end;
46}
47
48
49/**
50 * Pick the chosen trait from the traits array.
51 *
52 * @param traits the traits array.
53 * @param ret where to store the result.
54 * @param trait type of the trait to extract.
55 * @param index index number of the object to extract.
56 * @return #GNUNET_OK if no error occurred, #GNUNET_SYSERR otherwise.
57 */
58int
59GNUNET_TESTING_get_trait (const struct GNUNET_TESTING_Trait *traits,
60 const void **ret,
61 const char *trait,
62 unsigned int index)
63{
64 for (unsigned int i = 0; NULL != traits[i].trait_name; i++)
65 {
66 if ( (0 == strcmp (trait, traits[i].trait_name)) &&
67 (index == traits[i].index) )
68 {
69 *ret = (void *) traits[i].ptr;
70 return GNUNET_OK;
71 }
72 }
73 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
74 "Trait %s/%u not found.\n",
75 trait, index);
76
77 return GNUNET_SYSERR;
78}
79
80
81/* end of testing_api_traits.c */
diff --git a/src/testing/testing_cmds.h b/src/testing/testing_cmds.h
deleted file mode 100644
index 7a5860aea..000000000
--- a/src/testing/testing_cmds.h
+++ /dev/null
@@ -1,90 +0,0 @@
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 */
diff --git a/src/testing/topo.sh b/src/testing/topo.sh
deleted file mode 100755
index 090c3053f..000000000
--- a/src/testing/topo.sh
+++ /dev/null
@@ -1,95 +0,0 @@
1#!/bin/bash
2
3declare -A K_PLUGIN
4declare -A R_TCP
5declare -A R_UDP
6declare -A P_PLUGIN
7
8extract_attributes()
9{
10 line_key=$1
11 line=$2
12
13 if [ "$line_key" = "P" ]
14 then
15 n=$(echo $line|cut -d \| -f 1|awk -F: '{print $2}')
16 echo $n
17 m=$(echo $line|cut -d \| -f 1|awk -F: '{print $3}')
18 echo $m
19 else
20 number=$(echo $line|cut -d \| -f 1| cut -c 2-|cut -d : -f 2 )
21 echo $number
22 fi
23
24
25 nf=$(echo $line|awk -F: '{print NF}')
26 for ((i=2;i<=$nf;i++))
27 do
28 entry=$(echo $line |awk -v i=$i -F\| '{print $i}')
29 key=$(echo $entry|cut -d { -f 2|cut -d } -f 1|cut -d : -f 1)
30 value=$(echo $entry|cut -d { -f 2|cut -d } -f 1|cut -d : -f 2)
31 if [ "$key" = "tcp_port" ]
32 then
33 echo tcp port: $value
34 R_TCP[$number]=$value
35 elif [ "$key" = "udp_port" ]
36 then
37 echo udp port: $value
38 R_UDP[$number]=$value
39 elif [ "$key" = "plugin" ]
40 then
41 echo plugin: $value
42 echo $line_key
43 if [ "$line_key" = "P" ]
44 then
45 P_PLUGIN[$n,$m]=$value
46 echo $n $m ${P_PLUGIN[$n,$m]}
47 elif [ "$line_key" = "K" ]
48 then
49 K_PLUGIN[$number]=$value
50 fi
51 fi
52 done
53}
54
55read_topology(){
56
57local filename=$1
58while read line; do
59# reading each line
60 echo $line
61 key=$(cut -c -1 <<< $line)
62 if [ "$key" = "M" ]
63 then
64 LOCAL_M=$(cut -d : -f 2 <<< $line)
65 echo $LOCAL_M
66 elif [ "$key" = "N" ]
67 then
68 GLOBAL_N=$(cut -d : -f 2 <<< $line)
69 echo $GLOBAL_N
70 elif [ "$key" = "X" ]
71 then
72 KNOWN=$(cut -d : -f 2 <<< $line)
73 echo $KNOWN
74 elif [ "$key" = "T" ]
75 then
76 PLUGIN=$(cut -d : -f 2 <<< $line)
77 echo $PLUGIN
78 elif [ "$key" = "K" ]
79 then
80 echo know node
81 extract_attributes $key $line
82 elif [ "$key" = "R" ]
83 then
84 echo router
85 extract_attributes $key $line
86 elif [ "$key" = "P" ]
87 then
88 echo node
89 extract_attributes $key $line
90 fi
91done < $filename
92}
93
94
95