summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authort3sserakt <t3ss@posteo.de>2021-07-16 21:05:11 +0200
committert3sserakt <t3ss@posteo.de>2021-07-16 21:05:11 +0200
commit33830e71f8e80334e0c8cf5527b1f2b20804485e (patch)
treebe8bb3af17046a3e7c77ca6f11639c24e938211d
parent71f230fbb6f270f6b501934acadb6f57026c353d (diff)
- started to implement several cmds to start peers^Ctestcase plugin will be started directly from helper, functionality to communicate between master cmd loop and local cmd loop, code compiles, test is not working atm.
-rw-r--r--src/include/gnunet_protocols.h20
-rw-r--r--src/include/gnunet_testbed_ng_service.h9
-rw-r--r--src/include/gnunet_testing_ng_lib.h1
-rw-r--r--src/include/gnunet_testing_plugin.h12
-rw-r--r--src/testbed/Makefile.am11
-rw-r--r--src/testbed/gnunet-cmd.c54
-rw-r--r--src/testbed/gnunet-cmds-helper.c (renamed from src/testbed/gnunet-helper-cmds.c)480
-rwxr-xr-xsrc/testbed/netjail_exec.sh2
-rw-r--r--src/testbed/plugin_testcmd.c19
-rw-r--r--src/testbed/testbed_api.h3
-rw-r--r--src/testbed/testbed_api_cmd_block_until_all_peers_started.c102
-rw-r--r--src/testbed/testbed_api_cmd_netjail_start.c6
-rw-r--r--src/testbed/testbed_api_cmd_netjail_start_testbed.c162
-rw-r--r--src/testbed/testbed_api_cmd_send_peer_ready.c102
-rw-r--r--src/testbed/testbed_helper.h46
-rw-r--r--src/testing/testing_api_cmd_start_peer.c296
-rw-r--r--src/testing/testing_api_cmd_system_create.c110
-rw-r--r--src/testing/testing_api_loop.c3
-rw-r--r--src/transport/transport-testing.c4
-rw-r--r--src/transport/transport-testing2.c4
-rw-r--r--src/util/child_management.c19
21 files changed, 1239 insertions, 226 deletions
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index 8e6e8b1be..1d33d986d 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -3549,6 +3549,26 @@ extern "C" {
/*********************************************************************************/
+/*********************************************************************************/
+/********************************** Cmd Testing **********************************/
+/*********************************************************************************/
+
+/**
+ * The initialization message towards gnunet-cmds-helper
+ */
+#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT 1700
+
+/**
+ * The reply message from gnunet-cmds-helper
+ */
+#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY 1701
+
+#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED 1702
+
+#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED 1703
+
+/*********************************************************************************/
+
/**
* Type used to match 'all' message types.
*/
diff --git a/src/include/gnunet_testbed_ng_service.h b/src/include/gnunet_testbed_ng_service.h
index 9845b3be6..2ea5e616c 100644
--- a/src/include/gnunet_testbed_ng_service.h
+++ b/src/include/gnunet_testbed_ng_service.h
@@ -265,4 +265,13 @@ int
GNUNET_TESTBED_get_trait_hosts (const struct
GNUNET_TESTING_Command *cmd,
struct GNUNET_TESTBED_Host ***hosts);
+
+struct GNUNET_TESTING_Command
+GNUNET_TESTING_cmd_block_until_all_peers_started (const char *label,
+ unsigned int *
+ all_peers_started);
+
+struct GNUNET_TESTING_Command
+GNUNET_TESTING_cmd_send_peer_ready (const char *label,
+ TESTBED_CMD_HELPER_write_cb write_message);
#endif
diff --git a/src/include/gnunet_testing_ng_lib.h b/src/include/gnunet_testing_ng_lib.h
index a794562a9..8927fd4f1 100644
--- a/src/include/gnunet_testing_ng_lib.h
+++ b/src/include/gnunet_testing_ng_lib.h
@@ -28,6 +28,7 @@
#define GNUNET_TESTING_NG_LIB_H
#include "gnunet_util_lib.h"
+#include "gnunet_testing_plugin.h"
/* ********************* Helper functions ********************* */
diff --git a/src/include/gnunet_testing_plugin.h b/src/include/gnunet_testing_plugin.h
index 527f509ad..6a54cacd2 100644
--- a/src/include/gnunet_testing_plugin.h
+++ b/src/include/gnunet_testing_plugin.h
@@ -36,9 +36,17 @@ extern "C"
#endif
#endif
+typedef void
+(*TESTBED_CMD_HELPER_write_cb) (struct GNUNET_MessageHeader *message, size_t
+ msg_length);
+
+typedef void
+(*GNUNET_TESTING_PLUGIN_StartTestCase) (TESTBED_CMD_HELPER_write_cb
+ write_message, char *router_ip,
+ char *node_ip);
typedef void
-(*GNUNET_TESTING_PLUGIN_StartTestCase) ();
+(*GNUNET_TESTING_PLUGIN_ALL_PEERS_STARTED) ();
struct GNUNET_TESTING_PluginFunctions
{
@@ -48,6 +56,8 @@ struct GNUNET_TESTING_PluginFunctions
void *cls;
GNUNET_TESTING_PLUGIN_StartTestCase start_testcase;
+
+ GNUNET_TESTING_PLUGIN_ALL_PEERS_STARTED all_peers_started;
};
#if 0 /* keep Emacsens' auto-indent happy */
diff --git a/src/testbed/Makefile.am b/src/testbed/Makefile.am
index 8c4a6342b..dc24eaf26 100644
--- a/src/testbed/Makefile.am
+++ b/src/testbed/Makefile.am
@@ -24,7 +24,7 @@ endif
libexec_PROGRAMS = \
gnunet-cmd \
- gnunet-helper-cmds \
+ gnunet-cmds-helper \
gnunet-service-testbed \
gnunet-helper-testbed \
gnunet-daemon-testbed-blacklist \
@@ -45,6 +45,7 @@ libgnunet_plugin_testcmd_la_SOURCES = \
libgnunet_plugin_testcmd_la_LIBADD = \
$(top_builddir)/src/util/libgnunetutil.la \
$(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/testbed/libgnunettestbed.la
$(LTLIBINTL)
libgnunet_plugin_testcmd_la_LDFLAGS = \
$(GN_PLUGIN_LDFLAGS)
@@ -94,9 +95,9 @@ gnunet_cmd_LDADD = $(XLIB) \
libgnunettestbed.la \
$(LTLIBINTL) $(Z_LIBS)
-gnunet_helper_cmds_SOURCES = \
- gnunet-helper-cmds.c
-gnunet_helper_cmds_LDADD = $(XLIB) \
+gnunet_cmds_helper_SOURCES = \
+ gnunet-cmds-helper.c
+gnunet_cmds_helper_LDADD = $(XLIB) \
$(top_builddir)/src/util/libgnunetutil.la \
$(top_builddir)/src/testing/libgnunettesting.la \
libgnunettestbed.la \
@@ -124,6 +125,8 @@ lib_LTLIBRARIES = \
libgnunettestbed.la
libgnunettestbed_la_SOURCES = \
+ testbed_api_cmd_send_peer_ready.c \
+ testbed_api_cmd_block_until_all_peers_started.c \
testbed_api_cmd_netjail_start.c \
testbed_api_cmd_netjail_start_testbed.c \
testbed_api_cmd_netjail_stop_testbed.c \
diff --git a/src/testbed/gnunet-cmd.c b/src/testbed/gnunet-cmd.c
index 477c3c454..7889750ba 100644
--- a/src/testbed/gnunet-cmd.c
+++ b/src/testbed/gnunet-cmd.c
@@ -36,6 +36,9 @@
*/
#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
+#define NODE_BASE_IP "192.168.15."
+
+#define ROUTER_BASE_IP "92.68.150."
/**
* Handle for a plugin.
@@ -51,29 +54,44 @@ struct Plugin
* Plugin API.
*/
struct GNUNET_TESTING_PluginFunctions *api;
+
+ char *node_ip;
+
+ char *plugin_name;
+
+ char *global_n;
+
+ char *local_m;
+
+ char *n;
+
+ char *m;
};
/**
* Main function to run the test cases.
*
- * @param cls not used.
+ * @param cls plugin to use.
*
*/
static void
run (void *cls)
{
- struct Plugin *plugin;
+ struct Plugin *plugin = cls;
+ char *router_ip;
+ char *node_ip;
+
+ router_ip = GNUNET_malloc (strlen (ROUTER_BASE_IP) + strlen (plugin->m) + 1);
+ strcpy (router_ip, ROUTER_BASE_IP);
+ strcat (router_ip, plugin->m);
+
+ node_ip = GNUNET_malloc (strlen (NODE_BASE_IP) + strlen (plugin->n) + 1);
+ strcat (node_ip, NODE_BASE_IP);
+ strcat (node_ip, plugin->n);
+
+ plugin->api->start_testcase (NULL, router_ip, node_ip);
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "gnunet-cmd",
- "running plugin.\n");
- LOG (GNUNET_ERROR_TYPE_ERROR,
- "running plugin.\n");
- plugin = GNUNET_new (struct Plugin);
- plugin->api = GNUNET_PLUGIN_load ("libgnunet_plugin_testcmd",
- NULL);
- plugin->library_name = GNUNET_strdup ("libgnunet_plugin_testcmd");
- plugin->api->start_testcase ();
}
@@ -81,13 +99,25 @@ int
main (int argc, char *const *argv)
{
int rv = 0;
+ struct Plugin *plugin;
GNUNET_log_setup ("gnunet-cmd",
"DEBUG",
NULL);
+ plugin = GNUNET_new (struct Plugin);
+ plugin->api = GNUNET_PLUGIN_load (argv[0],
+ NULL);
+ plugin->library_name = GNUNET_strdup (argv[0]);
+
+ plugin->global_n = argv[1];
+ plugin->local_m = argv[2];
+ plugin->n = argv[3];
+ plugin->m = argv[4];
+
GNUNET_SCHEDULER_run (&run,
- NULL);
+ plugin);
+ GNUNET_free (plugin);
return rv;
}
diff --git a/src/testbed/gnunet-helper-cmds.c b/src/testbed/gnunet-cmds-helper.c
index 3073ebdfb..693892a9c 100644
--- a/src/testbed/gnunet-helper-cmds.c
+++ b/src/testbed/gnunet-cmds-helper.c
@@ -19,7 +19,7 @@
*/
/**
- * @file testbed/gnunet-helper-cmds.c
+ * @file testbed/gnunet-cmds-helper.c
* @brief Helper binary that is started from a remote interpreter loop to start
* a local interpreter loop.
*
@@ -42,7 +42,9 @@
#include "gnunet_testbed_service.h"
#include "testbed_helper.h"
#include "testbed_api.h"
+#include "gnunet_testing_plugin.h"
#include <zlib.h>
+#include "execinfo.h"
/**
* Generic logging shortcut
@@ -54,6 +56,50 @@
*/
#define LOG_DEBUG(...) LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
+#define NODE_BASE_IP "192.168.15."
+
+#define ROUTER_BASE_IP "92.68.150."
+
+#define MAX_TRACE_DEPTH 50
+
+/**
+ * Handle for a plugin.
+ */
+struct Plugin
+{
+ /**
+ * Name of the shared library.
+ */
+ char *library_name;
+
+ /**
+ * Plugin API.
+ */
+ struct GNUNET_TESTING_PluginFunctions *api;
+
+ char *node_ip;
+
+ char *plugin_name;
+
+ char *global_n;
+
+ char *local_m;
+
+ char *n;
+
+ char *m;
+};
+
+struct NodeIdentifier
+{
+ char *n;
+
+ char *m;
+
+ char *global_n;
+
+ char *local_m;
+};
/**
* Context for a single write on a chunk of memory
@@ -76,6 +122,8 @@ struct WriteContext
size_t pos;
};
+struct Plugin *plugin;
+
/**
* The process handle to the testbed service
*/
@@ -132,6 +180,61 @@ static int done_reading;
static int status;
+struct BacktraceInfo
+{
+ /**
+ * Array of strings which make up a backtrace from the point when this
+ * task was scheduled (essentially, who scheduled the task?)
+ */
+ char **backtrace_strings;
+
+ /**
+ * Size of the backtrace_strings array
+ */
+ int num_backtrace_strings;
+};
+
+/**
+ * Output stack trace of task @a t.
+ *
+ * @param t task to dump stack trace of
+ */
+static void
+dump_backtrace (struct BacktraceInfo *t)
+{
+
+ for (unsigned int i = 0; i < t->num_backtrace_strings; i++)
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Task %p trace %u: %s\n",
+ t,
+ i,
+ t->backtrace_strings[i]);
+
+}
+
+
+/**
+ * Initialize backtrace data for task @a t
+ *
+ * @param t task to initialize
+ */
+static void
+init_backtrace ()
+{
+ struct BacktraceInfo *t;
+ void *backtrace_array[MAX_TRACE_DEPTH];
+
+ t = GNUNET_new (struct BacktraceInfo);
+ t->num_backtrace_strings
+ = backtrace (backtrace_array, MAX_TRACE_DEPTH);
+ t->backtrace_strings =
+ backtrace_symbols (backtrace_array,
+ t->num_backtrace_strings);
+ dump_backtrace (t);
+
+}
+
+
/**
* Task to shut down cleanly
*
@@ -140,7 +243,11 @@ static int status;
static void
shutdown_task (void *cls)
{
- LOG_DEBUG ("Shutting down\n");
+
+ init_backtrace ();
+ LOG_DEBUG ("Shutting down.\n");
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Shutting down tokenizer!\n");
if (NULL != read_task_id)
{
@@ -176,6 +283,8 @@ shutdown_task (void *cls)
}
+
+
/**
* Task to write to the standard out
*
@@ -187,6 +296,9 @@ write_task (void *cls)
struct WriteContext *wc = cls;
ssize_t bytes_wrote;
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Writing data!\n");
+
GNUNET_assert (NULL != wc);
write_task_id = NULL;
bytes_wrote = GNUNET_DISK_file_write (stdout_fd,
@@ -194,7 +306,8 @@ write_task (void *cls)
wc->length - wc->pos);
if (GNUNET_SYSERR == bytes_wrote)
{
- LOG (GNUNET_ERROR_TYPE_WARNING, "Cannot reply back configuration\n");
+ LOG (GNUNET_ERROR_TYPE_WARNING,
+ "Cannot reply back successful initialization\n");
GNUNET_free (wc->data);
GNUNET_free (wc);
return;
@@ -204,8 +317,12 @@ write_task (void *cls)
{
GNUNET_free (wc->data);
GNUNET_free (wc);
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Written successfully!\n");
return;
}
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Written data!\n");
write_task_id = GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
stdout_fd,
&write_task,
@@ -240,6 +357,52 @@ child_death_task (void *cls)
}
+static void
+write_message (struct GNUNET_MessageHeader *message, size_t msg_length)
+{
+ struct WriteContext *wc;
+
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "enter write_message!\n");
+ wc = GNUNET_new (struct WriteContext);
+ wc->length = msg_length;
+ wc->data = message;
+ write_task_id = GNUNET_SCHEDULER_add_write_file (
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ stdout_fd,
+ &write_task,
+ wc);
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "leave write_message!\n");
+}
+
+
+/**
+ * Function to run the test cases.
+ *
+ * @param cls plugin to use.
+ *
+ */
+static void
+run_plugin (void *cls)
+{
+ struct Plugin *plugin = cls;
+ char *router_ip;
+ char *node_ip;
+
+ router_ip = GNUNET_malloc (strlen (ROUTER_BASE_IP) + strlen (plugin->m) + 1);
+ strcpy (router_ip, ROUTER_BASE_IP);
+ strcat (router_ip, plugin->m);
+
+ node_ip = GNUNET_malloc (strlen (NODE_BASE_IP) + strlen (plugin->n) + 1);
+ strcat (node_ip, NODE_BASE_IP);
+ strcat (node_ip, plugin->n);
+
+ plugin->api->start_testcase (&write_message, router_ip, node_ip);
+
+}
+
+
/**
* Functions with this signature are called whenever a
* complete message is received by the tokenizer.
@@ -255,191 +418,140 @@ child_death_task (void *cls)
static int
tokenizer_cb (void *cls, const struct GNUNET_MessageHeader *message)
{
- const struct GNUNET_TESTBED_HelperInit *msg;
- struct GNUNET_TESTBED_HelperReply *reply;
- struct GNUNET_CONFIGURATION_Handle *cfg;
- struct WriteContext *wc;
+ struct NodeIdentifier *ni = cls;
+ const struct GNUNET_CMDS_HelperInit *msg;
+ struct GNUNET_CMDS_HelperReply *reply;
char *binary;
- char *trusted_ip;
- char *hostname;
- char *config;
- char *xconfig;
- char *evstr;
- // char *str;
- size_t config_size;
- uLongf ul_config_size;
- size_t xconfig_size;
- uint16_t trusted_ip_size;
- uint16_t hostname_size;
+ char *plugin_name;
+ size_t plugin_name_size;
uint16_t msize;
+ size_t msg_length;
+ char *router_ip;
+ char *node_ip;
+
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "tokenizer \n");
msize = ntohs (message->size);
- if ((sizeof(struct GNUNET_TESTBED_HelperInit) >= msize) ||
- (GNUNET_MESSAGE_TYPE_TESTBED_HELPER_INIT != ntohs (message->type)))
+ if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED == ntohs (
+ message->type))
{
- LOG (GNUNET_ERROR_TYPE_WARNING, "Received unexpected message -- exiting\n");
- goto error;
- }
- msg = (const struct GNUNET_TESTBED_HelperInit *) message;
- trusted_ip_size = ntohs (msg->trusted_ip_size);
- trusted_ip = (char *) &msg[1];
- if ('\0' != trusted_ip[trusted_ip_size])
- {
- LOG (GNUNET_ERROR_TYPE_WARNING, "Trusted IP cannot be empty -- exiting\n");
- goto error;
- }
- hostname_size = ntohs (msg->hostname_size);
- if ((sizeof(struct GNUNET_TESTBED_HelperInit) + trusted_ip_size + 1
- + hostname_size) >= msize)
- {
- GNUNET_break (0);
- LOG (GNUNET_ERROR_TYPE_WARNING, "Received unexpected message -- exiting\n");
- goto error;
+ plugin->api->all_peers_started ();
}
- ul_config_size = (uLongf) ntohs (msg->config_size);
- config = GNUNET_malloc (ul_config_size);
- xconfig_size = msize - (trusted_ip_size + 1 + hostname_size
- + sizeof(struct GNUNET_TESTBED_HelperInit));
- int ret = uncompress ((Bytef *) config,
- &ul_config_size,
- (const Bytef *) (trusted_ip + trusted_ip_size + 1
- + hostname_size),
- (uLongf) xconfig_size);
- if (Z_OK != ret)
+ else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT == ntohs (message->type))
{
- switch (ret)
+ msg = (const struct GNUNET_CMDS_HelperInit *) message;
+ plugin_name_size = ntohs (msg->plugin_name_size);
+ if ((sizeof(struct GNUNET_CMDS_HelperInit) + plugin_name_size) > msize)
{
- case Z_MEM_ERROR:
- LOG (GNUNET_ERROR_TYPE_ERROR, "Not enough memory for decompression\n");
- break;
+ GNUNET_break (0);
+ LOG (GNUNET_ERROR_TYPE_WARNING,
+ "Received unexpected message -- exiting\n");
+ goto error;
+ }
+ plugin_name = GNUNET_malloc (plugin_name_size + 1);
+ GNUNET_strlcpy (plugin_name,
+ ((char *) &msg[1]),
+ plugin_name_size + 1);
- case Z_BUF_ERROR:
- LOG (GNUNET_ERROR_TYPE_ERROR, "Output buffer too small\n");
- break;
+ binary = GNUNET_OS_get_libexec_binary_path ("gnunet-cmd");
- case Z_DATA_ERROR:
- LOG (GNUNET_ERROR_TYPE_ERROR, "Data corrupted/incomplete\n");
- break;
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "plugin_name: %s \n",
+ plugin_name);
+
+ // cmd_binary_process = GNUNET_OS_start_process (
+ /*GNUNET_OS_INHERIT_STD_ERR verbose? ,
+ NULL,
+ NULL,
+ NULL,
+ binary,
+ plugin_name,
+ ni->global_n,
+ ni->local_m,
+ ni->n,
+ ni->m,
+ NULL);*/
+
+ plugin = GNUNET_new (struct Plugin);
+ plugin->api = GNUNET_PLUGIN_load (plugin_name,
+ NULL);
+ plugin->library_name = GNUNET_strdup (plugin_name);
+
+ plugin->global_n = ni->global_n;
+ plugin->local_m = ni->local_m;
+ plugin->n = ni->n;
+ plugin->m = ni->m;
+
+ router_ip = GNUNET_malloc (strlen (ROUTER_BASE_IP) + strlen (plugin->m)
+ + 1);
+ strcpy (router_ip, ROUTER_BASE_IP);
+ strcat (router_ip, plugin->m);
+
+ node_ip = GNUNET_malloc (strlen (NODE_BASE_IP) + strlen (plugin->n) + 1);
+ strcat (node_ip, NODE_BASE_IP);
+ strcat (node_ip, plugin->n);
+
+ plugin->api->start_testcase (&write_message, router_ip, node_ip);
- default:
- GNUNET_break (0);
- }
LOG (GNUNET_ERROR_TYPE_ERROR,
- "Error while uncompressing config -- exiting\n");
- GNUNET_free (config);
- goto error;
- }
- cfg = GNUNET_CONFIGURATION_create ();
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_deserialize (cfg, config, ul_config_size, NULL))
- {
- LOG (GNUNET_ERROR_TYPE_ERROR, "Unable to deserialize config -- exiting\n");
- GNUNET_free (config);
- goto error;
- }
- GNUNET_free (config);
- hostname = NULL;
- if (0 != hostname_size)
- {
- hostname = GNUNET_malloc (hostname_size + 1);
- GNUNET_strlcpy (hostname,
- ((char *) &msg[1]) + trusted_ip_size + 1,
- hostname_size + 1);
- }
- /* unset GNUNET_TESTING_PREFIX if present as it is more relevant for testbed */
- evstr = getenv (GNUNET_TESTING_PREFIX);
- if (NULL != evstr)
- {
- /* unsetting the variable will invalidate the pointer! */
- evstr = GNUNET_strdup (evstr);
- GNUNET_break (0 == unsetenv (GNUNET_TESTING_PREFIX));
- }
- test_system =
- GNUNET_TESTING_system_create ("testbed-helper", trusted_ip, hostname, NULL);
- if (NULL != evstr)
- {
- char *evar;
+ "We got here!\n");
- GNUNET_asprintf (&evar, GNUNET_TESTING_PREFIX "=%s", evstr);
- GNUNET_assert (0 == putenv (evar)); /* consumes 'evar',
- see putenv(): becomes part of environment! */
- GNUNET_free (evstr);
- evstr = NULL;
- }
- GNUNET_free (hostname);
- hostname = NULL;
- GNUNET_assert (NULL != test_system);
- GNUNET_assert (GNUNET_OK ==
- GNUNET_TESTING_configuration_create (test_system, cfg));
- GNUNET_assert (GNUNET_OK ==
- GNUNET_CONFIGURATION_get_value_filename (cfg,
- "PATHS",
- "DEFAULTCONFIG",
- &config));
- if (GNUNET_OK != GNUNET_CONFIGURATION_write (cfg, config))
- {
- LOG (GNUNET_ERROR_TYPE_WARNING,
- "Unable to write config file: %s -- exiting\n",
- config);
- GNUNET_CONFIGURATION_destroy (cfg);
- GNUNET_free (config);
- goto error;
- }
- LOG_DEBUG ("Staring testbed with config: %s\n", config);
- binary = GNUNET_OS_get_libexec_binary_path ("gnunet-cmd");
- {
- char *evar;
+ /*if (NULL == cmd_binary_process)
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Starting plugin failed!\n");
+ return GNUNET_SYSERR;
+ }*/
- /* expose testbed configuration through env variable */
- GNUNET_asprintf (&evar, "%s=%s", ENV_TESTBED_CONFIG, config);
- GNUNET_assert (0 == putenv (evar)); /* consumes 'evar',
- see putenv(): becomes part of environment! */
- evstr = NULL;
- }
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "We got here 2!\n");
+
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "global_n: %s local_n: %s n: %s m: %s.\n",
+ ni->global_n,
+ ni->local_m,
+ ni->n,
+ ni->m);
+
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "We got here 3!\n");
- cmd_binary_process = GNUNET_OS_start_process (
- GNUNET_OS_INHERIT_STD_ERR /*verbose? */,
- NULL,
- NULL,
- NULL,
- binary);
+ GNUNET_free (binary);
+
+ done_reading = GNUNET_YES;
+
+ msg_length = sizeof(struct GNUNET_CMDS_HelperReply);
+ reply = GNUNET_new (struct GNUNET_CMDS_HelperReply);
+ reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY);
+ reply->header.size = htons ((uint16_t) msg_length);
+
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "We got here 4!\n");
- if (NULL == cmd_binary_process)
+ write_message ((struct GNUNET_MessageHeader *) reply, msg_length);
+
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "We got here 5!\n");
+
+ /*child_death_task_id = GNUNET_SCHEDULER_add_read_file (
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ),
+ &child_death_task,
+ NULL);*/
+ return GNUNET_OK;
+ }
+ else
{
- return GNUNET_SYSERR;
+ LOG (GNUNET_ERROR_TYPE_WARNING, "Received unexpected message -- exiting\n");
+ goto error;
}
- GNUNET_free (binary);
- GNUNET_free (config);
-
- done_reading = GNUNET_YES;
- config = GNUNET_CONFIGURATION_serialize (cfg, &config_size);
- GNUNET_CONFIGURATION_destroy (cfg);
- cfg = NULL;
- xconfig_size =
- GNUNET_TESTBED_compress_config_ (config, config_size, &xconfig);
- GNUNET_free (config);
- wc = GNUNET_new (struct WriteContext);
- wc->length = xconfig_size + sizeof(struct GNUNET_TESTBED_HelperReply);
- reply = GNUNET_realloc (xconfig, wc->length);
- memmove (&reply[1], reply, xconfig_size);
- reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_HELPER_REPLY);
- reply->header.size = htons ((uint16_t) wc->length);
- reply->config_size = htons ((uint16_t) config_size);
- wc->data = reply;
- write_task_id = GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
- stdout_fd,
- &write_task,
- wc);
- child_death_task_id = GNUNET_SCHEDULER_add_read_file (
- GNUNET_TIME_UNIT_FOREVER_REL,
- GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ),
- &child_death_task,
- NULL);
- return GNUNET_OK;
error:
status = GNUNET_SYSERR;
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "tokenizer shuting down!\n");
GNUNET_SCHEDULER_shutdown ();
return GNUNET_SYSERR;
}
@@ -461,6 +573,8 @@ read_task (void *cls)
if ((GNUNET_SYSERR == sread) || (0 == sread))
{
LOG_DEBUG ("STDIN closed\n");
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "tokenizer shuting down during reading!\n");
GNUNET_SCHEDULER_shutdown ();
return;
}
@@ -468,6 +582,8 @@ read_task (void *cls)
{
/* didn't expect any more data! */
GNUNET_break_op (0);
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "tokenizer shuting down during reading, didn't expect any more data!\n");
GNUNET_SCHEDULER_shutdown ();
return;
}
@@ -478,6 +594,8 @@ read_task (void *cls)
GNUNET_MST_from_buffer (tokenizer, buf, sread, GNUNET_NO, GNUNET_NO))
{
GNUNET_break (0);
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "tokenizer shuting down during reading, writing to buffer failed!\n");
GNUNET_SCHEDULER_shutdown ();
return;
}
@@ -503,8 +621,11 @@ run (void *cls,
const char *cfgfile,
const struct GNUNET_CONFIGURATION_Handle *cfg)
{
+ struct NodeIdentifier *ni = cls;
+
LOG_DEBUG ("Starting interpreter loop helper...\n");
- tokenizer = GNUNET_MST_create (&tokenizer_cb, NULL);
+
+ tokenizer = GNUNET_MST_create (&tokenizer_cb, ni);
stdin_fd = GNUNET_DISK_get_handle_from_native (stdin);
stdout_fd = GNUNET_DISK_get_handle_from_native (stdout);
read_task_id = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
@@ -545,14 +666,28 @@ sighandler_child_death ()
int
main (int argc, char **argv)
{
+ struct NodeIdentifier *ni;
struct GNUNET_SIGNAL_Context *shc_chld;
struct GNUNET_GETOPT_CommandLineOption options[] =
{ GNUNET_GETOPT_OPTION_END };
int ret;
- GNUNET_log_setup ("gnunet-helper-cmds",
+ GNUNET_log_setup ("gnunet-cmds-helper",
"DEBUG",
NULL);
+ ni = GNUNET_new (struct NodeIdentifier);
+ ni->global_n = argv[1];
+ ni->local_m = argv[2];
+ ni->n = argv[3];
+ ni->m = argv[4];
+
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "global_n: %s local_n: %s n: %s m: %s.\n",
+ ni->global_n,
+ ni->local_m,
+ ni->n,
+ ni->m);
+
status = GNUNET_OK;
if (NULL ==
(sigpipe = GNUNET_DISK_pipe (GNUNET_DISK_PF_NONE)))
@@ -564,18 +699,21 @@ main (int argc, char **argv)
GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, &sighandler_child_death);
ret = GNUNET_PROGRAM_run (argc,
argv,
- "gnunet-helper-cmds",
+ "gnunet-cmds-helper",
"Helper for starting a local interpreter loop",
options,
&run,
- NULL);
+ ni);
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "run finished\n");
GNUNET_SIGNAL_handler_uninstall (shc_chld);
shc_chld = NULL;
GNUNET_DISK_pipe_close (sigpipe);
+ GNUNET_free (ni);
if (GNUNET_OK != ret)
return 1;
return (GNUNET_OK == status) ? 0 : 1;
}
-/* end of gnunet-helper-testbed.c */
+/* end of gnunet-cmds-helper.c */
diff --git a/src/testbed/netjail_exec.sh b/src/testbed/netjail_exec.sh
index 3e5d39c1c..532f4711c 100755
--- a/src/testbed/netjail_exec.sh
+++ b/src/testbed/netjail_exec.sh
@@ -13,4 +13,4 @@ NODE=$(netjail_print_name "N" $N $M)
-netjail_node_exec_without_fds $NODE $3
+netjail_node_exec_without_fds $NODE $3 $4 $5 $1 $2
diff --git a/src/testbed/plugin_testcmd.c b/src/testbed/plugin_testcmd.c
index 90e4a90a1..6f28e102d 100644
--- a/src/testbed/plugin_testcmd.c
+++ b/src/testbed/plugin_testcmd.c
@@ -26,21 +26,32 @@
#include "platform.h"
#include "gnunet_testing_ng_lib.h"
#include "gnunet_util_lib.h"
-#include "gnunet_testing_plugin.h"
-
-
+#include "gnunet_testbed_ng_service.h"
+unsigned int are_all_peers_started;
+static void
+all_peers_started ()
+{
+ are_all_peers_started = GNUNET_YES;
+}
static void
-start_testcase ()
+start_testcase (TESTBED_CMD_HELPER_write_cb write_message, char *router_ip,
+ char *node_ip)
{
struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
+ are_all_peers_started = GNUNET_NO;
+
struct GNUNET_TESTING_Command commands[] = {
GNUNET_TESTING_cmd_hello_world_birth ("hello-world-birth-0",
&now),
GNUNET_TESTING_cmd_hello_world ("hello-world-0","hello-world-birth-0",""),
+ GNUNET_TESTING_cmd_send_peer_ready ("send-peer-ready-1",
+ write_message),
+ GNUNET_TESTING_cmd_block_until_all_peers_started ("block-1",
+ &are_all_peers_started),
GNUNET_TESTING_cmd_end ()
};
diff --git a/src/testbed/testbed_api.h b/src/testbed/testbed_api.h
index ea78a14ff..9a54ca36c 100644
--- a/src/testbed/testbed_api.h
+++ b/src/testbed/testbed_api.h
@@ -40,7 +40,7 @@
/**
* Cmds Helper binary name
*/
-#define HELPER_CMDS_BINARY "gnunet-helper-cmds"
+#define HELPER_CMDS_BINARY "gnunet-cmds-helper"
/**
@@ -185,7 +185,6 @@ struct OperationContext
typedef void
(*TESTBED_opcq_empty_cb) (void *cls);
-
/**
* Handle to interact with a GNUnet testbed controller. Each
* controller has at least one master handle which is created when the
diff --git a/src/testbed/testbed_api_cmd_block_until_all_peers_started.c b/src/testbed/testbed_api_cmd_block_until_all_peers_started.c
new file mode 100644
index 000000000..fc872311d
--- /dev/null
+++ b/src/testbed/testbed_api_cmd_block_until_all_peers_started.c
@@ -0,0 +1,102 @@
+/*
+ This file is part of GNUnet
+ Copyright (C) 2021 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
+
+/**
+ * @file testing_api_cmd_block_until_all_peers_started.c
+ * @brief cmd to block the interpreter loop until all peers started.
+ * @author t3sserakt
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_testing_ng_lib.h"
+
+struct BlockState
+{
+ unsigned int *all_peers_started;
+};
+
+
+static int
+block_until_all_peers_started_traits (void *cls,
+ const void **ret,
+ const char *trait,
+ unsigned int index)
+{
+ return GNUNET_OK;
+}
+
+
+static void
+block_until_all_peers_started_cleanup (void *cls,
+ const struct GNUNET_TESTING_Command *cmd)
+{
+ struct BlockState *bs = cls;
+
+ GNUNET_free (bs);
+}
+
+
+static void
+block_until_all_peers_started_run (void *cls,
+ const struct GNUNET_TESTING_Command *cmd,
+ struct GNUNET_TESTING_Interpreter *is)
+{
+}
+
+
+static int
+block_until_all_peers_started_finish (void *cls,
+ GNUNET_SCHEDULER_TaskCallback cont,
+ void *cont_cls)
+{
+ struct BlockState *bs = cls;
+ unsigned int *ret = bs->all_peers_started;
+
+ return *ret;
+}
+
+
+/**
+ * Create command.
+ *
+ * @param label name for command.
+ * @return command.
+ */
+struct GNUNET_TESTING_Command
+GNUNET_TESTING_cmd_block_until_all_peers_started (const char *label,
+ unsigned int *
+ all_peers_started)
+{
+ struct BlockState *bs;
+
+ bs = GNUNET_new (struct BlockState);
+ bs->all_peers_started = all_peers_started;
+
+ struct GNUNET_TESTING_Command cmd = {
+ .cls = bs,
+ .label = label,
+ .run = &block_until_all_peers_started_run,
+ .finish = &block_until_all_peers_started_finish,
+ .cleanup = &block_until_all_peers_started_cleanup,
+ .traits = &block_until_all_peers_started_traits
+ };
+
+ return cmd;
+}
diff --git a/src/testbed/testbed_api_cmd_netjail_start.c b/src/testbed/testbed_api_cmd_netjail_start.c
index 320537a61..1e37d5475 100644
--- a/src/testbed/testbed_api_cmd_netjail_start.c
+++ b/src/testbed/testbed_api_cmd_netjail_start.c
@@ -59,6 +59,9 @@ netjail_start_cleanup (void *cls,
{
struct NetJailState *ns = cls;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "netjail_start_cleanup!\n");
+
if (NULL != ns->cwh)
{
GNUNET_wait_child_cancel (ns->cwh);
@@ -74,6 +77,7 @@ netjail_start_cleanup (void *cls,
GNUNET_OS_process_destroy (ns->start_proc);
ns->start_proc = NULL;
}
+ GNUNET_free (ns);
}
@@ -108,6 +112,8 @@ child_completed_callback (void *cls,
}
else
{
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Child completed with an error!\n");
ns->finished = GNUNET_SYSERR;
}
GNUNET_OS_process_destroy (ns->start_proc);
diff --git a/src/testbed/testbed_api_cmd_netjail_start_testbed.c b/src/testbed/testbed_api_cmd_netjail_start_testbed.c
index dc8196e94..585825cbc 100644
--- a/src/testbed/testbed_api_cmd_netjail_start_testbed.c
+++ b/src/testbed/testbed_api_cmd_netjail_start_testbed.c
@@ -28,13 +28,36 @@
#include "gnunet_testbed_ng_service.h"
#include "testbed_api.h"
#include "testbed_api_hosts.h"
+#include "testbed_helper.h"
#define NETJAIL_EXEC_SCRIPT "./netjail_exec.sh"
+struct HelperMessage;
+
+struct HelperMessage
+{
+
+ struct HelperMessage *next;
+
+ struct HelperMessage *prev;
+
+ /**
+ * Size of the original message.
+ */
+ uint16_t bytes_msg;
+
+ /* Followed by @e bytes_msg of msg.*/
+};
+
+
struct NetJailState
{
+ struct HelperMessage *hp_messages_head;
+
+ struct HelperMessage *hp_messages_tail;
+
/**
* The process handle
*/
@@ -64,6 +87,8 @@ struct NetJailState
unsigned int number_of_testbeds_started;
+ unsigned int number_of_peers_started;
+
/**
* The host where the controller is running
*/
@@ -112,7 +137,7 @@ netjail_exec_traits (void *cls,
{
struct NetJailState *ns = cls;
struct GNUNET_HELPER_Handle **helper = ns->helper;
- struct GNUNET_TESTBED_Host **hosts = ns->host;
+ struct HelperMessage *hp_messages_head = ns->hp_messages_head;
struct GNUNET_TESTING_Trait traits[] = {
@@ -123,8 +148,8 @@ netjail_exec_traits (void *cls,
},
{
.index = 1,
- .trait_name = "hosts",
- .ptr = (const void *) hosts,
+ .trait_name = "hp_msgs_head",
+ .ptr = (const void *) hp_messages_head,
},
GNUNET_TESTING_trait_end ()
};
@@ -162,13 +187,14 @@ GNUNET_TESTBED_get_trait_helper_handles (const struct
* @return #GNUNET_OK on success.
*/
int
-GNUNET_TESTBED_get_trait_hosts (const struct
- GNUNET_TESTING_Command *cmd,
- struct GNUNET_TESTBED_Host ***hosts)
+GNUNET_TESTBED_get_trait_helper_messages (const struct
+ GNUNET_TESTING_Command *cmd,
+ struct HelperMessage ***
+ hp_messages_head)
{
return cmd->traits (cmd->cls,
- (const void **) hosts,
- "hosts",
+ (const void **) hp_messages_head,
+ "hp_msgs_head",
(unsigned int) 1);
}
@@ -214,15 +240,32 @@ helper_mst (void *cls, const struct GNUNET_MessageHeader *message)
{
struct TestbedCount *tbc = cls;
struct NetJailState *ns = tbc->ns;
- struct GNUNET_TESTBED_Host *host = ns->host[tbc->count - 1];
+ struct HelperMessage *hp_msg;
+
+ if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY == ntohs (message->type))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "helper_mst tbc->count: %d\n",
+ tbc->count);
+ // GNUNET_TESTBED_extract_cfg (host, message);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received message from helper.\n");
+ ns->number_of_testbeds_started++;
+ }
+ else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED == ntohs (
+ message->type))
+ {
+ ns->number_of_peers_started++;
+ }
+ else
+ {
+ hp_msg = GNUNET_new (struct HelperMessage);
+ hp_msg->bytes_msg = message->size;
+ memcpy (&hp_msg[1], message, message->size);
+ GNUNET_CONTAINER_DLL_insert (ns->hp_messages_head, ns->hp_messages_tail,
+ hp_msg);
+ }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "helper_mst tbc->count: %d\n",
- tbc->count);
- GNUNET_TESTBED_extract_cfg (host, message);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received message from helper.\n");
- ns->number_of_testbeds_started++;
return GNUNET_OK;
}
@@ -235,6 +278,32 @@ exp_cb (void *cls)
}
+static struct GNUNET_CMDS_HelperInit *
+create_helper_init_msg_ (char *m_char,
+ char *n_char,
+ const char *plugin_name)
+{
+ struct GNUNET_CMDS_HelperInit *msg;
+ uint16_t plugin_name_len;
+ uint16_t msg_size;
+
+ GNUNET_assert (NULL != plugin_name);
+ plugin_name_len = strlen (plugin_name);
+ msg_size = sizeof(struct GNUNET_CMDS_HelperInit) + plugin_name_len;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "msg_size: %d \n",
+ msg_size);
+ msg = GNUNET_malloc (msg_size);
+ msg->header.size = htons (msg_size);
+ msg->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT);
+ msg->plugin_name_size = htons (plugin_name_len);
+ GNUNET_memcpy ((char *) &msg[1],
+ plugin_name,
+ plugin_name_len);
+ return msg;
+}
+
+
static void
start_testbed (struct NetJailState *ns, struct
GNUNET_CONFIGURATION_Handle *config,
@@ -242,13 +311,15 @@ start_testbed (struct NetJailState *ns, struct
char *m_char)
{
struct GNUNET_CONFIGURATION_Handle *cfg;
- struct GNUNET_TESTBED_HelperInit *msg;
+ struct GNUNET_CMDS_HelperInit *msg;
struct TestbedCount *tbc;
char *const script_argv[] = {NETJAIL_EXEC_SCRIPT,
- m_char,
n_char,
+ m_char,
GNUNET_OS_get_libexec_binary_path (
HELPER_CMDS_BINARY),
+ ns->global_n,
+ ns->local_m,
NULL};
unsigned int m = atoi (m_char);
unsigned int n = atoi (n_char);
@@ -291,7 +362,9 @@ start_testbed (struct NetJailState *ns, struct
struct GNUNET_HELPER_Handle *helper = ns->helper[tbc->count - 1];
- msg = GNUNET_TESTBED_create_helper_init_msg_ ("127.0.0.1", NULL, config);
+ msg = create_helper_init_msg_ (m_char,
+ n_char,
+ "libgnunet_plugin_testcmd");
GNUNET_array_append (ns->msg, ns->n_msg, &msg->header);
GNUNET_array_append (ns->shandle, ns->n_shandle, GNUNET_HELPER_send (
@@ -300,6 +373,10 @@ start_testbed (struct NetJailState *ns, struct
GNUNET_NO,
&clear_msg,
tbc));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Message send!\n");
+
if (NULL == ns->shandle[tbc->count - 1])
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -348,14 +425,49 @@ netjail_start_finish (void *cls,
{
unsigned int ret = GNUNET_NO;
struct NetJailState *ns = cls;
+ unsigned int total_number = atoi (ns->local_m) * atoi (ns->global_n);
+ struct GNUNET_CMDS_PEER_STARTED *reply;
+ size_t msg_length;
+ struct GNUNET_HELPER_Handle *helper;
+ struct TestbedCount *tbc;
- if (ns->number_of_testbeds_started == atoi (ns->local_m) * atoi (
- ns->global_n))
+ if (ns->number_of_testbeds_started == total_number)
{
- ret = GNUNET_YES;
- cont (cont_cls);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "All helper started!\n");
+ /* ret = GNUNET_YES;
+ cont (cont_cls);*/
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "All helpers started!\n");
+ }
+
+ if (ns->number_of_peers_started == total_number)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "All peers started!\n");
+
+ for (int i = 1; i <= atoi (ns->global_n); i++) {
+ for (int j = 1; j <= atoi (ns->local_m); j++)
+ {
+ tbc = GNUNET_new (struct TestbedCount);
+ tbc->ns = ns;
+ tbc->count = (j - 1) * atoi (ns->local_m) + i + atoi (ns->global_n)
+ * atoi (ns->local_m);
+ helper = ns->helper[tbc->count - 1];
+ msg_length = sizeof(struct GNUNET_CMDS_ALL_PEERS_STARTED);
+ reply = GNUNET_new (struct GNUNET_CMDS_ALL_PEERS_STARTED);
+ reply->header.type = htons (
+ GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED);
+ reply->header.size = htons ((uint16_t) msg_length);
+
+ GNUNET_array_append (ns->msg, ns->n_msg, &reply->header);
+
+ GNUNET_array_append (ns->shandle, ns->n_shandle, GNUNET_HELPER_send (
+ helper,
+ &reply->header,
+ GNUNET_NO,
+ &clear_msg,
+ tbc));
+ }
+ }
}
return ret;
}
diff --git a/src/testbed/testbed_api_cmd_send_peer_ready.c b/src/testbed/testbed_api_cmd_send_peer_ready.c
new file mode 100644
index 000000000..8a82b23a8
--- /dev/null
+++ b/src/testbed/testbed_api_cmd_send_peer_ready.c
@@ -0,0 +1,102 @@
+/*
+ This file is part of GNUnet
+ Copyright (C) 2021 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
+
+/**
+ * @file testing_api_cmd_send_peer_ready.c
+ * @brief cmd to send a helper message if peer is ready.
+ * @author t3sserakt
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_testing_ng_lib.h"
+
+
+struct SendPeerReadyState
+{
+ TESTBED_CMD_HELPER_write_cb write_message;
+
+ struct GNUNET_CMDS_PEER_STARTED *reply;
+};
+
+
+static int
+send_peer_ready_traits (void *cls,
+ const void **ret,
+ const char *trait,
+ unsigned int index)
+{
+ return GNUNET_OK;
+}
+
+
+static void
+send_peer_ready_cleanup (void *cls,
+ const struct GNUNET_TESTING_Command *cmd)
+{
+ struct SendPeerReadyState *sprs = cls;
+
+ GNUNET_free (sprs->reply);
+ GNUNET_free (sprs);
+}
+
+
+static void
+send_peer_ready_run (void *cls,
+ const struct GNUNET_TESTING_Command *cmd,
+ struct GNUNET_TESTING_Interpreter *is)
+{
+ /*struct SendPeerReadyState *sprs = cls;
+ struct GNUNET_CMDS_PEER_STARTED *reply;
+ size_t msg_length;
+
+ msg_length = sizeof(struct GNUNET_CMDS_PEER_STARTED);
+ reply = GNUNET_new (struct GNUNET_CMDS_PEER_STARTED);
+ reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED);
+ reply->header.size = htons ((uint16_t) msg_length);
+ sprs->reply = reply;
+ sprs->write_message ((struct GNUNET_MessageHeader *) reply, msg_length);*/
+}
+
+
+/**
+ * Create command.
+ *
+ * @param label name for command.
+ * @return command.
+ */
+struct GNUNET_TESTING_Command
+GNUNET_TESTING_cmd_send_peer_ready (const char *label,
+ TESTBED_CMD_HELPER_write_cb write_message)
+{
+ struct SendPeerReadyState *sprs;
+
+ sprs = GNUNET_new (struct SendPeerReadyState);
+ sprs->write_message = write_message;
+
+ struct GNUNET_TESTING_Command cmd = {
+ .cls = sprs,
+ .label = label,
+ .run = &send_peer_ready_run,
+ .cleanup = &send_peer_ready_cleanup,
+ .traits = &send_peer_ready_traits
+ };
+
+ return cmd;
+}
diff --git a/src/testbed/testbed_helper.h b/src/testbed/testbed_helper.h
index 817ad559d..84059fef2 100644
--- a/src/testbed/testbed_helper.h
+++ b/src/testbed/testbed_helper.h
@@ -84,6 +84,52 @@ struct GNUNET_TESTBED_HelperReply
* un-compressed */
};
+/**
+ * Initialization message for gnunet-cmds-testbed to start cmd binary.
+ */
+struct GNUNET_CMDS_HelperInit
+{
+ /**
+ * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ *
+ */
+ uint16_t plugin_name_size GNUNET_PACKED;
+
+ /* Followed by plugin name of the plugin running the test case. This is not NULL
+ * terminated */
+};
+
+/**
+ * Reply message from cmds helper process
+ */
+struct GNUNET_CMDS_HelperReply
+{
+ /**
+ * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY
+ */
+ struct GNUNET_MessageHeader header;
+};
+
+struct GNUNET_CMDS_PEER_STARTED
+{
+ /**
+ * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED
+ */
+ struct GNUNET_MessageHeader header;
+};
+
+struct GNUNET_CMDS_ALL_PEERS_STARTED
+{
+ /**
+ * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED
+ */
+ struct GNUNET_MessageHeader header;
+};
+
GNUNET_NETWORK_STRUCT_END
#endif
/* end of testbed_helper.h */
diff --git a/src/testing/testing_api_cmd_start_peer.c b/src/testing/testing_api_cmd_start_peer.c
new file mode 100644
index 000000000..0f8c618b8
--- /dev/null
+++ b/src/testing/testing_api_cmd_start_peer.c
@@ -0,0 +1,296 @@
+/*
+ This file is part of GNUnet
+ Copyright (C) 2021 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
+
+/**
+ * @file testing_api_cmd_start_peer.c
+ * @brief cmd to start a peer.
+ * @author t3sserakt
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_testing_ng_lib.h"
+
+
+struct StartPeerState
+{
+ /**
+ * Receive callback
+ */
+ struct GNUNET_MQ_MessageHandler *handlers;
+
+ const char *cfgname;
+
+ /**
+ * Peer's configuration
+ */
+ struct GNUNET_CONFIGURATION_Handle *cfg;
+
+ struct GNUNET_TESTING_Peer *peer;
+
+ /**
+ * Peer identity
+ */
+ struct GNUNET_PeerIdentity id;
+
+ /**
+ * Peer's transport service handle
+ */
+ struct GNUNET_TRANSPORT_CoreHandle *th;
+
+ /**
+ * Application handle
+ */
+ struct GNUNET_TRANSPORT_ApplicationHandle *ah;
+
+ /**
+ * Peer's PEERSTORE Handle
+ */
+ struct GNUNET_PEERSTORE_Handle *ph;
+
+ /**
+ * Hello get task
+ */
+ struct GNUNET_SCHEDULER_Task *rh_task;
+
+ /**
+ * Peer's transport get hello handle to retrieve peer's HELLO message
+ */
+ struct GNUNET_PEERSTORE_IterateContext *pic;
+
+ /**
+ * Hello
+ */
+ char *hello;
+
+ /**
+ * Hello size
+ */
+ size_t hello_size;
+
+ char *m;
+
+ char *n;
+
+ unsigned int finished;
+};
+
+
+static void
+retrieve_hello (void *cls);
+
+static void
+hello_iter_cb (void *cb_cls,
+ const struct GNUNET_PEERSTORE_Record *record,
+ const char *emsg)
+{
+ struct StartPeerState *sps = cb_cls;
+ if (NULL == record)
+ {
+ sps->pic = NULL;
+ sps->rh_task = GNUNET_SCHEDULER_add_now (retrieve_hello, p);
+ return;
+ }
+ // Check record type et al?
+ sps->hello_size = record->value_size;
+ sps->hello = GNUNET_malloc (sps->hello_size);
+ memcpy (sps->hello, record->value, sps->hello_size);
+ p->hello[p->hello_size - 1] = '\0';
+
+ GNUNET_PEERSTORE_iterate_cancel (sps->pic);
+ sps->pic = NULL;
+ sps->finished = GNUNET_YES;
+}
+
+
+static void
+retrieve_hello (void *cls)
+{
+ struct StartPeerState *sps = cls;
+ sps->rh_task = NULL;
+ sps->pic = GNUNET_PEERSTORE_iterate (sps->ph,
+ "transport",
+ &sps->id,
+ GNUNET_PEERSTORE_TRANSPORT_HELLO_KEY,
+ hello_iter_cb,
+ sps);
+
+}
+
+static int
+start_peer_finish (void *cls,
+ GNUNET_SCHEDULER_TaskCallback cont,
+ void *cont_cls)
+{
+ struct StartPeerState *sps = cls;
+
+ return sps->finished;
+}
+
+
+static void
+start_peer_run (void *cls,
+ const struct GNUNET_TESTING_Command *cmd,
+ struct GNUNET_TESTING_Interpreter *is)
+{
+ struct StartPeerState *sps = cls;
+ char *emsg = NULL;
+ struct GNUNET_PeerIdentity dummy;
+
+ if (GNUNET_NO == GNUNET_DISK_file_test (sps->cfgname))
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "File not found: `%s'\n",
+ cfgname);
+ return NULL;
+ }
+
+ if (NULL != handlers)
+ {
+ for (i = 0; NULL != handlers[i].cb; i++)
+ ;
+ sps->handlers = GNUNET_new_array (i + 1,
+ struct GNUNET_MQ_MessageHandler);
+ GNUNET_memcpy (sps->handlers,
+ handlers,
+ i * sizeof(struct GNUNET_MQ_MessageHandler));
+ }
+ sps->cfg = GNUNET_CONFIGURATION_create ();
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CONFIGURATION_load (sps->cfg, sps->cfgname));
+ if (GNUNET_SYSERR ==
+ GNUNET_TESTING_configuration_create (tl_system,
+ sps->cfg))
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Testing library failed to create unique configuration based on `%s'\n",
+ sps->cfgname);
+ GNUNET_CONFIGURATION_destroy (sps->cfg);
+ GNUNET_TESTING_interpreter_fail ();
+ }
+
+ sps->peer = GNUNET_TESTING_peer_configure (tth->tl_system,
+ p->cfg,
+ p->no,
+ NULL,
+ &emsg);
+ if (NULL == sps->peer)
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Testing library failed to create unique configuration based on `%s': `%s'\n",
+ cfgname,
+ emsg);
+ GNUNET_free (emsg);
+ GNUNET_TESTING_interpreter_fail ();
+ }
+
+ if (GNUNET_OK != GNUNET_TESTING_peer_start (p->peer))
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Testing library failed to create unique configuration based on `%s'\n",
+ cfgname);
+ GNUNET_free (emsg);
+ GNUNET_TESTING_interpreter_fail ();
+ }
+
+ memset (&dummy,
+ '\0',
+ sizeof(dummy));
+ GNUNET_TESTING_peer_get_identity (sps->peer,
+ &sps->id);
+ if (0 == memcmp (&dummy,
+ &sps->id,
+ sizeof(struct GNUNET_PeerIdentity)))
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Testing library failed to obtain peer identity for peer %s_%s\n",
+ p->no);
+ GNUNET_free (emsg);
+ GNUNET_TESTING_interpreter_fail ();
+ }
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Peer %u configured with identity `%s'\n",
+ p->no,
+ GNUNET_i2s_full (&p->id));
+ sps->th = GNUNET_TRANSPORT_core_connect (p->cfg,
+ NULL,
+ handlers,
+ p,
+ &notify_connect,
+ &notify_disconnect);
+ if (NULL == sps->th)
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to connect to transport service for peer `%s': `%s'\n",
+ cfgname,
+ emsg);
+ GNUNET_free (emsg);
+ GNUNET_TESTING_interpreter_fail ();
+ }
+ sps->ph = GNUNET_PEERSTORE_connect (p->cfg);
+ if (NULL == sps->th)
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to connect to peerstore service for peer `%s': `%s'\n",
+ cfgname,
+ emsg);
+ GNUNET_free (emsg);
+ GNUNET_TESTING_interpreter_fail ();
+ }
+ sps->ah = GNUNET_TRANSPORT_application_init (p->cfg);
+ if (NULL == sps->ah)
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to initialize the TRANSPORT application suggestion client handle for peer `%s': `%s'\n",
+ cfgname,
+ emsg);
+ GNUNET_free (emsg);
+ GNUNET_TESTING_interpreter_fail ();
+ }
+ p->rh_task = GNUNET_SCHEDULER_add_now (retrieve_hello, p);
+}
+
+
+/**
+ * Create command.
+ *
+ * @param label name for command.
+ * @return command.
+ */
+struct GNUNET_TESTING_Command
+GNUNET_TESTING_cmd_start_peer (const char *label,
+ char *m,
+ char *n)
+{
+ struct StartPeerState *sps;
+
+ sps = GNUNET_new (struct StartPeerState);
+ sps->m = m;
+ sps->n = n;
+
+ struct GNUNET_TESTING_Command cmd = {
+ .cls = sps,
+ .label = label,
+ .run = &start_peer_run,
+ .cleanup = &start_peer_cleanup,
+ .traits = &start_peer_traits
+ };
+
+ return cmd;
+}
diff --git a/src/testing/testing_api_cmd_system_create.c b/src/testing/testing_api_cmd_system_create.c
new file mode 100644
index 000000000..ad0aa4f90
--- /dev/null
+++ b/src/testing/testing_api_cmd_system_create.c
@@ -0,0 +1,110 @@
+/*
+ This file is part of GNUnet
+ Copyright (C) 2021 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
+
+/**
+ * @file testing_api_cmd_system_create.c
+ * @brief cmd to create a testing system handle.
+ * @author t3sserakt
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_testing_ng_lib.h"
+
+struct TestSystemState
+{
+ struct GNUNET_TESTING_System *test_system;
+};
+
+
+static void
+system_create_run (void *cls,
+ const struct GNUNET_TESTING_Command *cmd,
+ struct GNUNET_TESTING_Interpreter *is)
+{
+ struct TestSystemState *tss = cls;
+
+ tss->test_system = GNUNET_TESTING_system_create (tss->testdir,
+ NULL,
+ NULL,
+ NULL);
+}
+
+static int
+system_create_traits (void *cls,
+ const void **ret,
+ const char *trait,
+ unsigned int index)
+{
+ struct TestSystemState *tss = cls;
+ struct GNUNET_TESTING_System *test_system = tss->test_system;
+
+ struct GNUNET_TESTING_Trait traits[] = {
+ {
+ .index = 0,
+ .trait_name = "test_system",
+ .ptr = (const void *) test_system,
+ },
+ GNUNET_TESTING_trait_end ()
+ };
+
+ return GNUNET_TESTING_get_trait (traits,
+ ret,
+ trait,
+ index);
+}
+
+
+int
+GNUNET_TESTING_get_trait_test_system (const struct
+ GNUNET_TESTING_Command *cmd,
+ struct GNUNET_TESTING_System **test_system)
+{
+ return cmd->traits (cmd->cls,
+ (const void **) test_system,
+ "test_system",
+ (unsigned int) 0);
+}
+
+
+/**
+ * Create command.
+ *
+ * @param label name for command.
+ * @return command.
+ */
+struct GNUNET_TESTING_Command
+GNUNET_TESTING_cmd_system_create (const char *label,
+ const char *testdir)
+{
+ struct TestSystemState *tss;
+
+ tss = GNUNET_new (struct TestSystemState);
+ tss->testdir = testdir;
+
+ struct GNUNET_TESTING_Command cmd = {
+ .cls = tss,
+ .label = label,
+ .run = &system_create_run,
+ .cleanup = &system_create_cleanup,
+ .traits = &system_create_traits
+ };
+
+ return cmd;
+}
diff --git a/src/testing/testing_api_loop.c b/src/testing/testing_api_loop.c
index 49ed48063..7b7dc010a 100644
--- a/src/testing/testing_api_loop.c
+++ b/src/testing/testing_api_loop.c
@@ -332,6 +332,9 @@ GNUNET_TESTING_interpreter_fail ()
if (GNUNET_SYSERR == is->result)
return; /* ignore, we already failed! */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "interpreter_fail!\n");
+
if (NULL != cmd)
{
while (GNUNET_TESTING_cmd_is_batch (cmd))
diff --git a/src/transport/transport-testing.c b/src/transport/transport-testing.c
index a7ee563d7..00c4a08dd 100644
--- a/src/transport/transport-testing.c
+++ b/src/transport/transport-testing.c
@@ -463,7 +463,7 @@ GNUNET_TRANSPORT_TESTING_start_peer (struct
GNUNET_free (emsg);
return NULL;
}
- GNUNET_free (emsg);
+
if (GNUNET_OK != GNUNET_TESTING_peer_start (p->peer))
{
LOG (GNUNET_ERROR_TYPE_ERROR,
@@ -508,6 +508,7 @@ GNUNET_TRANSPORT_TESTING_start_peer (struct
cfgname,
emsg);
GNUNET_TRANSPORT_TESTING_stop_peer (p);
+ GNUNET_free (emsg);
return NULL;
}
p->ats = GNUNET_ATS_connectivity_init (p->cfg);
@@ -518,6 +519,7 @@ GNUNET_TRANSPORT_TESTING_start_peer (struct
cfgname,
emsg);
GNUNET_TRANSPORT_TESTING_stop_peer (p);
+ GNUNET_free (emsg);
return NULL;
}
p->ghh = GNUNET_TRANSPORT_hello_get (p->cfg,
diff --git a/src/transport/transport-testing2.c b/src/transport/transport-testing2.c
index 482aaf4d0..6d41ec098 100644
--- a/src/transport/transport-testing2.c
+++ b/src/transport/transport-testing2.c
@@ -478,7 +478,7 @@ GNUNET_TRANSPORT_TESTING_start_peer (struct
GNUNET_free (emsg);
return NULL;
}
- GNUNET_free (emsg);
+
if (GNUNET_OK != GNUNET_TESTING_peer_start (p->peer))
{
LOG (GNUNET_ERROR_TYPE_ERROR,
@@ -520,6 +520,7 @@ GNUNET_TRANSPORT_TESTING_start_peer (struct
cfgname,
emsg);
GNUNET_TRANSPORT_TESTING_stop_peer (p);
+ GNUNET_free (emsg);
return NULL;
}
p->ats = GNUNET_ATS_connectivity_init (p->cfg);
@@ -530,6 +531,7 @@ GNUNET_TRANSPORT_TESTING_start_peer (struct
cfgname,
emsg);
GNUNET_TRANSPORT_TESTING_stop_peer (p);
+ GNUNET_free (emsg);
return NULL;
}
p->ph = GNUNET_PEERSTORE_connect (p->cfg);
diff --git a/src/util/child_management.c b/src/util/child_management.c
index 11fde4a61..3afd682b9 100644
--- a/src/util/child_management.c
+++ b/src/util/child_management.c
@@ -29,6 +29,11 @@
#include "gnunet_util_lib.h"
#include "gnunet_child_management_lib.h"
+/**
+ * Generic logging shortcut
+ */
+#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
+
/**
* Struct which defines a Child Wait handle
@@ -87,7 +92,7 @@ maint_child_death (void *cls)
(void) cls;
sig_task = NULL;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Received SIGCHLD.\n");
/* drain pipe */
@@ -193,6 +198,9 @@ GNUNET_wait_child (struct GNUNET_OS_Process *proc,
{
struct GNUNET_ChildWaitHandle *cwh;
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Adding child!\n");
+
child_management_start ();
cwh = GNUNET_new (struct GNUNET_ChildWaitHandle);
cwh->proc = proc;
@@ -216,9 +224,12 @@ GNUNET_wait_child (struct GNUNET_OS_Process *proc,
void
GNUNET_wait_child_cancel (struct GNUNET_ChildWaitHandle *cwh)
{
- GNUNET_CONTAINER_DLL_remove (cwh_head,
- cwh_tail,
- cwh);
+ if ((NULL != cwh_head))
+ {
+ GNUNET_CONTAINER_DLL_remove (cwh_head,
+ cwh_tail,
+ cwh);
+ }
if (NULL == cwh_head)
{
child_management_done ();