From d7fa0579995790840199ec86cb4d518f9d372fcd Mon Sep 17 00:00:00 2001 From: t3sserakt Date: Thu, 7 Oct 2021 13:07:30 +0200 Subject: - add generic topology configuration by file - cmd simple send using file configuration from file - added cmd to check the logs for backchannel encapsulation - added cmd which notifies the master loop of local loop being prepared to finish - added logging to helper.c - moved code from connecting peers cmd into global functions - added parameters given to the connecting peers cmd - added assertion when notifying the transport service about a new queue, if the communicator has no intial capacity - added optional valgrind cmd to test script - added flag für queues with unlimited length - added check for queues with higher priority - added attribute queue_capacity to struct Queue - bug fixing worker task for kce generation and transport notification about available queue in udp communicator - change value for unlimited queue length from 0 to UINT16_MAX in tcp communicator and service - added loop to stop the test system for the globally known peers in stop testsystem cmd - refactored endless growing array to handle further messages from the local loops, and added logic to handle the local test prepare msg - added utility methods in testing.c - added forwarding of all tests prepared msg in gnunet-cmds-helper.c - added cmd to end loop without shutdown - added without shutdown cmd to simple send testcase - added backchannel check, without shutdown and prepared cmd to udp backchannel testcase. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/testing/Makefile.am | 1 + src/testing/gnunet-cmds-helper.c | 10 + src/testing/test_testing_topology.c | 44 ++++ src/testing/testing.c | 264 ++++++++++++++++++++- src/testing/testing_api_cmd_local_test_finished.c | 2 +- src/testing/testing_api_cmd_local_test_prepared.c | 168 +++++++++++++ .../testing_api_cmd_netjail_start_testsystem_v2.c | 181 ++++++++++---- src/testing/testing_api_cmd_netjail_start_v2.c | 2 +- .../testing_api_cmd_netjail_stop_testsystem_v2.c | 22 +- src/testing/testing_api_loop.c | 19 +- src/testing/testing_cmds.h | 17 ++ 11 files changed, 674 insertions(+), 56 deletions(-) create mode 100644 src/testing/test_testing_topology.c create mode 100644 src/testing/testing_api_cmd_local_test_prepared.c (limited to 'src/testing') diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am index efb22b279..07caeb44e 100644 --- a/src/testing/Makefile.am +++ b/src/testing/Makefile.am @@ -44,6 +44,7 @@ libgnunet_test_testing_plugin_testcmd_la_LDFLAGS = \ libgnunettesting_la_SOURCES = \ testing_api_cmd_local_test_finished.c \ + testing_api_cmd_local_test_prepared.c \ testing_api_cmd_send_peer_ready.c \ testing_api_cmd_block_until_all_peers_started.c \ testing_api_cmd_block_until_external_trigger.c \ diff --git a/src/testing/gnunet-cmds-helper.c b/src/testing/gnunet-cmds-helper.c index e50db0cf6..4aeccb115 100644 --- a/src/testing/gnunet-cmds-helper.c +++ b/src/testing/gnunet-cmds-helper.c @@ -418,9 +418,19 @@ tokenizer_cb (void *cls, const struct GNUNET_MessageHeader *message) else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED == ntohs ( message->type)) { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "all peers started\n"); plugin->api->all_peers_started (); return GNUNET_OK; } + else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_LOCAL_TESTS_PREPARED == ntohs ( + message->type)) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "all local tests prepared\n"); + plugin->api->all_local_tests_prepared (); + return GNUNET_OK; + } else { LOG (GNUNET_ERROR_TYPE_WARNING, "Received unexpected message -- exiting\n"); diff --git a/src/testing/test_testing_topology.c b/src/testing/test_testing_topology.c new file mode 100644 index 000000000..cfc91e609 --- /dev/null +++ b/src/testing/test_testing_topology.c @@ -0,0 +1,44 @@ +/* + 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 . + + SPDX-License-Identifier: AGPL3.0-or-later + */ + +/** + * @file testbed/plugin_testcmd.c + * @brief a plugin to provide the API for running test cases. + * @author t3sserakt + */ +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_testing_ng_lib.h" + +#define LOG(kind, ...) GNUNET_log_from (kind, "testing-api", __VA_ARGS__) + +int +main (int argc, + char *const *argv) +{ + GNUNET_log_setup ("test-topology", + "DEBUG", + NULL); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Test\n"); + GNUNET_TESTING_get_topo_from_file ("topo.conf"); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Test2\n"); +} diff --git a/src/testing/testing.c b/src/testing/testing.c index a11d404a5..d3acd4689 100644 --- a/src/testing/testing.c +++ b/src/testing/testing.c @@ -37,6 +37,15 @@ #define LOG(kind, ...) GNUNET_log_from (kind, "testing-api", __VA_ARGS__) +#define CONNECT_ADDRESS_TEMPLATE "%s-192.168.15.%u:60002" + +#define ROUTER_CONNECT_ADDRESS_TEMPLATE "%s-92.68.150.%u:60002" + +#define KNOWN_CONNECT_ADDRESS_TEMPLATE "%s-92.68.151.%u:60002" + +#define PREFIX_TCP "tcp" + +#define PREFIX_UDP "udp" /** * Lowest port used for GNUnet testing. Should be high enough to not @@ -1900,7 +1909,7 @@ get_connect_value (char *line, struct GNUNET_TESTING_NetjailNode *node) unsigned int namespace_n; char *rest = NULL; char *rest2 = NULL; - struct GNUNET_TESTING_ADDRESS_PREFIX *prefix; + struct GNUNET_TESTING_AddressPrefix *prefix; node_connection = GNUNET_new (struct GNUNET_TESTING_NodeConnection); node_connection->node = node; @@ -1936,7 +1945,7 @@ get_connect_value (char *line, struct GNUNET_TESTING_NetjailNode *node) } while (NULL != (token = strtok_r (NULL, ":", &rest))) { - prefix = GNUNET_new (struct GNUNET_TESTING_ADDRESS_PREFIX); + prefix = GNUNET_new (struct GNUNET_TESTING_AddressPrefix); token2 = strtok_r (token, "}", &rest2); if (NULL != token2) { @@ -1958,13 +1967,12 @@ get_connect_value (char *line, struct GNUNET_TESTING_NetjailNode *node) GNUNET_CONTAINER_DLL_insert (node_connection->address_prefixes_head, node_connection->address_prefixes_tail, prefix); + LOG (GNUNET_ERROR_TYPE_ERROR, + "address_prefix %s\n", + prefix->address_prefix); } GNUNET_free (copy); - LOG (GNUNET_ERROR_TYPE_ERROR, - "address_prefix %s\n", - prefix->address_prefix); - return node_connection; } @@ -2006,6 +2014,250 @@ node_connections (char *line, struct GNUNET_TESTING_NetjailNode *node) } +static int +log_nodes (void *cls, const struct GNUNET_ShortHashCode *id, void *value) +{ + struct GNUNET_TESTING_NetjailNode *node = value; + struct GNUNET_TESTING_NodeConnection *pos_connection; + struct GNUNET_TESTING_AddressPrefix *pos_prefix; + + LOG (GNUNET_ERROR_TYPE_ERROR, + "plugin: %s space: %u node: %u global: %u\n", + node->plugin, + node->namespace_n, + node->node_n, + node->is_global); + + for (pos_connection = node->node_connections_head; NULL != pos_connection; + pos_connection = pos_connection->next) + { + + LOG (GNUNET_ERROR_TYPE_ERROR, + "namespace_n: %u node_n: %u node_type: %u\n", + pos_connection->namespace_n, + pos_connection->node_n, + pos_connection->node_type); + + for (pos_prefix = pos_connection->address_prefixes_head; NULL != pos_prefix; + pos_prefix = + pos_prefix->next) + { + LOG (GNUNET_ERROR_TYPE_ERROR, + "prefix: %s\n", + pos_prefix->address_prefix); + } + } + return GNUNET_YES; +} + + +static int +log_namespaces (void *cls, const struct GNUNET_ShortHashCode *id, void *value) +{ + struct GNUNET_TESTING_NetjailNamespace *namespace = value; + struct GNUNET_TESTING_NetjailRouter *router = namespace->router; + + LOG (GNUNET_ERROR_TYPE_ERROR, + "router_tcp: %u router_udp: %u spaces: %u\n", + router->tcp_port, + router->udp_port, + namespace->namespace_n); + GNUNET_CONTAINER_multishortmap_iterate (namespace->nodes, &log_nodes, NULL); + return GNUNET_YES; +} + + +static int +log_topo (struct GNUNET_TESTING_NetjailTopology *topology) +{ + LOG (GNUNET_ERROR_TYPE_ERROR, + "plugin: %s spaces: %u nodes: %u known: %u\n", + topology->plugin, + topology->namespaces_n, + topology->nodes_m, + topology->nodes_x); + + GNUNET_CONTAINER_multishortmap_iterate (topology->map_namespaces, + log_namespaces, NULL); + GNUNET_CONTAINER_multishortmap_iterate (topology->map_globals, &log_nodes, + NULL); + return GNUNET_YES; +} + + +/** + * Get the connections to other nodes for a specific node. + * + * @param num The specific node we want the connections for. + * @param topology The topology we get the connections from. + * @return The connections of the node. + */ +struct GNUNET_TESTING_NodeConnection * +GNUNET_TESTING_get_connections (unsigned int num, struct + GNUNET_TESTING_NetjailTopology *topology) +{ + struct GNUNET_TESTING_NetjailNode *node; + struct GNUNET_ShortHashCode *hkey; + struct GNUNET_HashCode hc; + struct GNUNET_TESTING_NetjailNamespace *namespace; + unsigned int namespace_n, node_m; + + log_topo (topology); + + hkey = GNUNET_new (struct GNUNET_ShortHashCode); + if (topology->nodes_x >= num) + { + + GNUNET_CRYPTO_hash (&num, sizeof(num), &hc); + memcpy (hkey, + &hc, + sizeof (*hkey)); + node = GNUNET_CONTAINER_multishortmap_get (topology->map_globals, + hkey); + } + else + { + namespace_n = (unsigned int) floor ((num - topology->nodes_x) + / topology->nodes_m); + LOG (GNUNET_ERROR_TYPE_ERROR, + "num: %u nodes_x: %u nodes_m: %u namespace_n: %u\n", + num, + topology->nodes_x, + topology->nodes_m, + namespace_n); + hkey = GNUNET_new (struct GNUNET_ShortHashCode); + GNUNET_CRYPTO_hash (&namespace_n, sizeof(namespace_n), &hc); + memcpy (hkey, + &hc, + sizeof (*hkey)); + namespace = GNUNET_CONTAINER_multishortmap_get (topology->map_namespaces, + hkey); + node_m = num - topology->nodes_x - topology->nodes_m * (namespace_n - 1); + hkey = GNUNET_new (struct GNUNET_ShortHashCode); + GNUNET_CRYPTO_hash (&node_m, sizeof(node_m), &hc); + memcpy (hkey, + &hc, + sizeof (*hkey)); + node = GNUNET_CONTAINER_multishortmap_get (namespace->nodes, + hkey); + } + + + return node->node_connections_head; +} + + +/** + * Retrieve the public key from the test system with the unique node id. + * + * @param num The unique node id. + * @param tl_system The test system. + * @return The peer identity wrapping the public key. + */ +struct GNUNET_PeerIdentity * +GNUNET_TESTING_get_pub_key (unsigned int num, struct + GNUNET_TESTING_System *tl_system) +{ + struct GNUNET_PeerIdentity *peer = GNUNET_new (struct GNUNET_PeerIdentity); + struct GNUNET_CRYPTO_EddsaPublicKey *pub_key = GNUNET_new (struct + GNUNET_CRYPTO_EddsaPublicKey); + struct GNUNET_CRYPTO_EddsaPrivateKey *priv_key = GNUNET_new (struct + GNUNET_CRYPTO_EddsaPrivateKey); + + priv_key = GNUNET_TESTING_hostkey_get (tl_system, + num, + peer); + + GNUNET_CRYPTO_eddsa_key_get_public (priv_key, + pub_key); + peer->public_key = *pub_key; + return peer; +} + + +/** + * Calculate the unique id identifying a node from a given connction. + * + * @param node_connection The connection we calculate the id from. + * @param topology The topology we get all needed information from. + * @return The unique id of the node from the connection. + */ +unsigned int +GNUNET_TESTING_calculate_num (struct + GNUNET_TESTING_NodeConnection *node_connection, + struct GNUNET_TESTING_NetjailTopology *topology) +{ + unsigned int n, m, num; + + n = node_connection->namespace_n; + m = node_connection->node_n; + + if (0 == n) + num = m; + else + num = (n - 1) * topology->nodes_m + m + topology->nodes_x; + + return num; +} + + +/** + * Get the address for a specific communicator from a connection. + * + * @param connection The connection we like to have the address from. + * @param prefix The communicator protocol prefix. + * @return The address of the communicator. + */ +char * +GNUNET_TESTING_get_address (struct GNUNET_TESTING_NodeConnection *connection, + char *prefix) +{ + struct GNUNET_TESTING_NetjailNode *node; + char *addr; + char *template; + + LOG (GNUNET_ERROR_TYPE_ERROR, + "node_n: %u\n", + connection->node_n); + + node = connection->node; + if (connection->namespace_n == node->namespace_n) + { + template = CONNECT_ADDRESS_TEMPLATE; + } + else if (0 == connection->namespace_n) + { + template = KNOWN_CONNECT_ADDRESS_TEMPLATE; + } + else + { + template = ROUTER_CONNECT_ADDRESS_TEMPLATE; + } + + if (0 == strcmp (PREFIX_TCP, prefix)) + { + + GNUNET_asprintf (&addr, + template, + prefix, + connection->node_n); + } + else if (0 == strcmp (PREFIX_UDP, prefix)) + { + GNUNET_asprintf (&addr, + template, + prefix, + connection->node_n); + } + else + { + GNUNET_break (0); + } + + return addr; +} + + /** * Getting the topology from file. * diff --git a/src/testing/testing_api_cmd_local_test_finished.c b/src/testing/testing_api_cmd_local_test_finished.c index 383de4c10..b50e471e9 100644 --- a/src/testing/testing_api_cmd_local_test_finished.c +++ b/src/testing/testing_api_cmd_local_test_finished.c @@ -115,7 +115,7 @@ local_test_finished_finish (void *cls, GNUNET_SCHEDULER_TaskCallback cont, void *cont_cls) { - LOG (GNUNET_ERROR_TYPE_DEBUG, + LOG (GNUNET_ERROR_TYPE_ERROR, "Stopping local loop\n"); return GNUNET_YES; } diff --git a/src/testing/testing_api_cmd_local_test_prepared.c b/src/testing/testing_api_cmd_local_test_prepared.c new file mode 100644 index 000000000..4e915c7c0 --- /dev/null +++ b/src/testing/testing_api_cmd_local_test_prepared.c @@ -0,0 +1,168 @@ +/* + 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 . + + SPDX-License-Identifier: AGPL3.0-or-later + */ + +/** + * @file testing_api_cmd_local_test_prepared.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" +#include "testing_cmds.h" + +/** + * Generic logging shortcut + */ +#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__) + + +/** + * Struct to hold information for callbacks. + * + */ +struct LocalPreparedState +{ + /** + * Callback to write messages to the master loop. + * + */ + TESTING_CMD_HELPER_write_cb write_message; + + /** + * The message send back to the master loop. + * + */ + struct GNUNET_CMDS_LOCAL_TEST_PREPARED *reply; + + /** + * Flag indicating if all local tests finished. + */ + unsigned int *all_local_tests_prepared; +}; + + +/** + * Trait function of this cmd does nothing. + * + */ +static int +local_test_prepared_traits (void *cls, + const void **ret, + const char *trait, + unsigned int index) +{ + return GNUNET_OK; +} + + +/** + * The cleanup function of this cmd frees resources the cmd allocated. + * + */ +static void +local_test_prepared_cleanup (void *cls, + const struct GNUNET_TESTING_Command *cmd) +{ + struct LocalPreparedState *lfs = cls; + + GNUNET_free (lfs->reply); + GNUNET_free (lfs); +} + + +/** + * This function sends a GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_TESTS_PREPARED message to the master loop. + * + */ +static void +local_test_prepared_run (void *cls, + const struct GNUNET_TESTING_Command *cmd, + struct GNUNET_TESTING_Interpreter *is) +{ + struct LocalPreparedState *lfs = cls; + + struct GNUNET_CMDS_LOCAL_TEST_PREPARED *reply; + size_t msg_length; + + msg_length = sizeof(struct GNUNET_CMDS_LOCAL_TEST_PREPARED); + reply = GNUNET_new (struct GNUNET_CMDS_LOCAL_TEST_PREPARED); + reply->header.type = htons ( + GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_TEST_PREPARED); + reply->header.size = htons ((uint16_t) msg_length); + lfs->reply = reply; + lfs->write_message ((struct GNUNET_MessageHeader *) reply, msg_length); +} + + +/** + * 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. + * + */ +static int +local_test_prepared_finish (void *cls, + GNUNET_SCHEDULER_TaskCallback cont, + void *cont_cls) +{ + struct LocalPreparedState *lfs = cls; + unsigned int *ret = lfs->all_local_tests_prepared; + + if (GNUNET_YES == *ret) + { + cont (cont_cls); + } + + return *ret; + +} + + +/** + * Create command. + * + * @param label name for command. + * @param write_message Callback to write messages to the master loop. + * @param all_local_tests_prepared Flag which will be set from outside. + * @return command. + */ +struct GNUNET_TESTING_Command +GNUNET_TESTING_cmd_local_test_prepared (const char *label, + TESTING_CMD_HELPER_write_cb + write_message, + unsigned int * + all_local_tests_prepared) +{ + struct LocalPreparedState *lfs; + + lfs = GNUNET_new (struct LocalPreparedState); + lfs->write_message = write_message; + lfs->all_local_tests_prepared = all_local_tests_prepared; + + struct GNUNET_TESTING_Command cmd = { + .cls = lfs, + .label = label, + .run = &local_test_prepared_run, + .finish = &local_test_prepared_finish, + .cleanup = &local_test_prepared_cleanup, + .traits = &local_test_prepared_traits + }; + + return cmd; +} diff --git a/src/testing/testing_api_cmd_netjail_start_testsystem_v2.c b/src/testing/testing_api_cmd_netjail_start_testsystem_v2.c index ccb3f5ae8..5e27a7a82 100644 --- a/src/testing/testing_api_cmd_netjail_start_testsystem_v2.c +++ b/src/testing/testing_api_cmd_netjail_start_testsystem_v2.c @@ -29,6 +29,11 @@ #define NETJAIL_EXEC_SCRIPT "./../testing/netjail_exec_v2.sh" +/** + * Generic logging shortcut + */ +#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__) + /** * Struct to store messages send/received by the helper into a DLL * @@ -116,13 +121,13 @@ struct NetJailState /** * The send handle for the helper */ - struct GNUNET_HELPER_SendHandle **shandle; + // struct GNUNET_HELPER_SendHandle **shandle; /** * Size of the array NetJailState#shandle. * */ - unsigned int n_shandle; + // unsigned int n_shandle; /** * The messages send to the helper. @@ -151,7 +156,13 @@ struct NetJailState * Number of local tests finished. * */ - unsigned int number_of_local_test_finished; + unsigned int number_of_local_tests_finished; + + /** + * Number of local tests prepared to finish. + * + */ + unsigned int number_of_local_tests_prepared; /** * Name of the test case plugin the helper will load. @@ -188,6 +199,17 @@ struct TestingSystemCount */ struct TestingSystemCount *prev; + /** + * The send handle for the helper + */ + struct GNUNET_HELPER_SendHandle *shandle;// **shandle; + + /** + * Size of the array NetJailState#shandle. + * + */ + // unsigned int n_shandle; + /** * The number of the test environment. * @@ -277,10 +299,9 @@ netjail_exec_traits (void *cls, * @return #GNUNET_OK on success. */ int -GNUNET_TESTING_get_trait_helper_handles_v2 (const struct - GNUNET_TESTING_Command *cmd, - struct GNUNET_HELPER_Handle *** - helper) +GNUNET_TESTING_get_trait_helper_handles_v2 ( + const struct GNUNET_TESTING_Command *cmd, + struct GNUNET_HELPER_Handle ***helper) { return cmd->traits (cmd->cls, (const void **) helper, @@ -293,18 +314,19 @@ GNUNET_TESTING_get_trait_helper_handles_v2 (const struct * Continuation function from GNUNET_HELPER_send() * * @param cls closure - * @param result GNUNET_OK on success, - * GNUNET_NO if helper process died - * GNUNET_SYSERR during GNUNET_HELPER_stop + * @param result #GNUNET_OK on success, + * #GNUNET_NO if helper process died + * #GNUNET_SYSERR during GNUNET_HELPER_stop */ static void -clear_msg (void *cls, int result) +clear_msg (void *cls, + int result) { struct TestingSystemCount *tbc = cls; struct NetJailState *ns = tbc->ns; - GNUNET_assert (NULL != ns->shandle[tbc->count - 1]); - ns->shandle[tbc->count - 1] = NULL; + GNUNET_assert (NULL != tbc->shandle);// [tbc->count - 1]); + tbc->shandle = NULL;// [tbc->count - 1] = NULL; GNUNET_free (ns->msg[tbc->count - 1]); ns->msg[tbc->count - 1] = NULL; } @@ -323,10 +345,11 @@ clear_msg (void *cls, int result) * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing */ static int -helper_mst (void *cls, const struct GNUNET_MessageHeader *message) +helper_mst (void *cls, + const struct GNUNET_MessageHeader *message) { - struct TestingSystemCount *tbc = cls; - struct NetJailState *ns = tbc->ns; + // struct TestingSystemCount *tbc = cls; + struct NetJailState *ns = cls;// tbc->ns; struct HelperMessage *hp_msg; if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY == ntohs (message->type)) @@ -338,10 +361,18 @@ helper_mst (void *cls, const struct GNUNET_MessageHeader *message) { ns->number_of_peers_started++; } + else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_TEST_PREPARED == ntohs ( + message->type)) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "received prepare msg %u\n", + ns->number_of_local_tests_prepared); + ns->number_of_local_tests_prepared++; + } else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED == ntohs ( message->type)) { - ns->number_of_local_test_finished++; + ns->number_of_local_tests_finished++; } else { @@ -364,8 +395,10 @@ static void exp_cb (void *cls) { struct NetJailState *ns = cls; + unsigned int *rv = ns->rv; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called exp_cb.\n"); - *ns->rv = 1; + *rv = 1; } @@ -420,6 +453,7 @@ start_helper (struct NetJailState *ns, struct struct GNUNET_TESTING_NetjailTopology *topology = ns->topology; struct GNUNET_TESTING_NetjailNode *node; struct GNUNET_TESTING_NetjailNamespace *namespace; + unsigned int *rv = ns->rv; if (0 == n) @@ -460,7 +494,8 @@ start_helper (struct NetJailState *ns, struct else tbc->count = (n - 1) * ns->local_m + m + ns->known; - GNUNET_CONTAINER_DLL_insert (ns->tbcs_head, ns->tbcs_tail, + GNUNET_CONTAINER_DLL_insert (ns->tbcs_head, + ns->tbcs_tail, tbc); @@ -469,14 +504,14 @@ start_helper (struct NetJailState *ns, struct GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No SUID for %s!\n", NETJAIL_EXEC_SCRIPT); - *ns->rv = 1; + *rv = 1; } else if (GNUNET_NO == helper_check) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s not found!\n", NETJAIL_EXEC_SCRIPT); - *ns->rv = 1; + *rv = 1; } GNUNET_array_append (ns->helper, ns->n_helper, GNUNET_HELPER_start ( @@ -485,7 +520,7 @@ start_helper (struct NetJailState *ns, struct script_argv, &helper_mst, &exp_cb, - tbc)); + ns)); helper = ns->helper[tbc->count - 1]; @@ -542,19 +577,20 @@ start_helper (struct NetJailState *ns, struct GNUNET_array_append (ns->msg, ns->n_msg, &msg->header); - GNUNET_array_append (ns->shandle, ns->n_shandle, GNUNET_HELPER_send ( - helper, - &msg->header, - GNUNET_NO, - &clear_msg, - tbc)); + // GNUNET_array_append (tbc->shandle, tbc->n_shandle, + tbc->shandle = GNUNET_HELPER_send ( + helper, + &msg->header, + GNUNET_NO, + &clear_msg, + tbc); // ); - if (NULL == ns->shandle[tbc->count - 1]) + if (NULL == tbc->shandle)// [tbc->count - 1]) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Send handle is NULL!\n"); GNUNET_free (msg); - *ns->rv = 1; + *rv = 1; } } @@ -595,39 +631,76 @@ netjail_exec_run (void *cls, static void -send_all_peers_started (unsigned int i, unsigned int j, struct NetJailState *ns) +send_message_to_locals ( + unsigned int i, + unsigned int j, + struct NetJailState *ns, + struct GNUNET_MessageHeader *header + ) { - unsigned int total_number = ns->local_m * ns->global_n + ns->known; - struct GNUNET_CMDS_ALL_PEERS_STARTED *reply; - size_t msg_length; + // unsigned int total_number = ns->local_m * ns->global_n + ns->known; struct GNUNET_HELPER_Handle *helper; struct TestingSystemCount *tbc; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "send message to locals\n"); tbc = GNUNET_new (struct TestingSystemCount); tbc->ns = ns; // 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. if (0 == i) - tbc->count = j + total_number; + tbc->count = j; // + total_number; else - tbc->count = (i - 1) * ns->local_m + j + total_number + ns->known; + tbc->count = (i - 1) * ns->local_m + j + ns->known; // + total_number ; - helper = ns->helper[tbc->count - 1 - total_number]; - 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); + helper = ns->helper[tbc->count - 1];// - total_number]; - GNUNET_array_append (ns->msg, ns->n_msg, &reply->header); + GNUNET_array_append (ns->msg, ns->n_msg, header); struct GNUNET_HELPER_SendHandle *sh = GNUNET_HELPER_send ( helper, - &reply->header, + header, GNUNET_NO, &clear_msg, tbc); - GNUNET_array_append (ns->shandle, ns->n_shandle, sh); + tbc->shandle = sh; + // GNUNET_array_append (tbc->shandle, tbc->n_shandle, sh); +} + + +static void +send_all_local_tests_prepared (unsigned int i, unsigned int j, struct + NetJailState *ns) +{ + struct GNUNET_CMDS_ALL_LOCAL_TESTS_PREPARED *reply; + size_t msg_length; + + + msg_length = sizeof(struct GNUNET_CMDS_ALL_LOCAL_TESTS_PREPARED); + reply = GNUNET_new (struct GNUNET_CMDS_ALL_LOCAL_TESTS_PREPARED); + reply->header.type = htons ( + GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_LOCAL_TESTS_PREPARED); + reply->header.size = htons ((uint16_t) msg_length); + + send_message_to_locals (i, j, ns, &reply->header); +} + + +static void +send_all_peers_started (unsigned int i, unsigned int j, struct NetJailState *ns) +{ + + struct GNUNET_CMDS_ALL_PEERS_STARTED *reply; + size_t msg_length; + + + 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); + + send_message_to_locals (i, j, ns, &reply->header); } @@ -650,12 +723,28 @@ netjail_start_finish (void *cls, unsigned int total_number = ns->local_m * ns->global_n + ns->known; - if (ns->number_of_local_test_finished == total_number) + if (ns->number_of_local_tests_finished == total_number) { ret = GNUNET_YES; cont (cont_cls); } + if (ns->number_of_local_tests_prepared == total_number) + { + for (int i = 1; i <= ns->known; i++) + { + send_all_local_tests_prepared (0,i, ns); + } + + for (int i = 1; i <= ns->global_n; i++) + { + for (int j = 1; j <= ns->local_m; j++) + { + send_all_local_tests_prepared (i,j, ns); + } + } + } + if (ns->number_of_testsystems_started == total_number) { ns->number_of_testsystems_started = 0; diff --git a/src/testing/testing_api_cmd_netjail_start_v2.c b/src/testing/testing_api_cmd_netjail_start_v2.c index 36fbb0e10..7d802db6a 100644 --- a/src/testing/testing_api_cmd_netjail_start_v2.c +++ b/src/testing/testing_api_cmd_netjail_start_v2.c @@ -75,7 +75,7 @@ netjail_start_cleanup (void *cls, { GNUNET_assert (0 == GNUNET_OS_process_kill (ns->start_proc, - SIGKILL)); + SIGTERM)); GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (ns->start_proc)); GNUNET_OS_process_destroy (ns->start_proc); diff --git a/src/testing/testing_api_cmd_netjail_stop_testsystem_v2.c b/src/testing/testing_api_cmd_netjail_stop_testsystem_v2.c index 8eccc5764..6ce106eaa 100644 --- a/src/testing/testing_api_cmd_netjail_stop_testsystem_v2.c +++ b/src/testing/testing_api_cmd_netjail_stop_testsystem_v2.c @@ -45,6 +45,12 @@ struct StopHelperState unsigned int local_m; unsigned int global_n; + + /** + * Number of global known nodes. + * + */ + unsigned int known; }; @@ -97,11 +103,24 @@ stop_testing_system_run (void *cls, GNUNET_TESTING_get_trait_helper_handles (start_helper_cmd, &helper); + for (int i = 1; i <= shs->known; i++) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "i: %u\n", + i); + GNUNET_HELPER_stop (helper[i - 1], + GNUNET_YES); + } + for (int i = 1; i <= shs->global_n; i++) { for (int j = 1; j <= shs->local_m; j++) { - GNUNET_HELPER_stop (helper[(i - 1) * shs->local_m + j - 1], + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "i: %u j: %u\n", + i, + j); + GNUNET_HELPER_stop (helper[(i - 1) * shs->local_m + j + shs->known - 1], GNUNET_YES); } } @@ -130,6 +149,7 @@ GNUNET_TESTING_cmd_stop_testing_system_v2 (const char *label, shs->helper_start_label = helper_start_label; shs->local_m = topology->nodes_m; shs->global_n = topology->namespaces_n; + shs->known = topology->nodes_x; struct GNUNET_TESTING_Command cmd = { .cls = shs, diff --git a/src/testing/testing_api_loop.c b/src/testing/testing_api_loop.c index 0c24c0e26..ab095aafa 100644 --- a/src/testing/testing_api_loop.c +++ b/src/testing/testing_api_loop.c @@ -408,6 +408,22 @@ GNUNET_TESTING_cmd_end (void) { static struct GNUNET_TESTING_Command cmd; cmd.label = NULL; + cmd.shutdown_on_end = GNUNET_YES; + + return cmd; +} + +/** + * Create command array terminator without shutdown. + * + * @return a end-command. + */ +struct GNUNET_TESTING_Command +GNUNET_TESTING_cmd_end_without_shutdown (void) +{ + static struct GNUNET_TESTING_Command cmd; + cmd.label = NULL; + cmd.shutdown_on_end = GNUNET_NO; return cmd; } @@ -447,7 +463,8 @@ interpreter_run (void *cls) "Running command END %p\n", is); is->result = GNUNET_OK; - GNUNET_SCHEDULER_shutdown (); + if (GNUNET_YES == cmd->shutdown_on_end) + GNUNET_SCHEDULER_shutdown (); return; } else if (NULL != cmd) diff --git a/src/testing/testing_cmds.h b/src/testing/testing_cmds.h index 7a5860aea..005402a73 100644 --- a/src/testing/testing_cmds.h +++ b/src/testing/testing_cmds.h @@ -85,6 +85,23 @@ struct GNUNET_CMDS_LOCAL_FINISHED struct GNUNET_MessageHeader header; }; +struct GNUNET_CMDS_LOCAL_TEST_PREPARED +{ + /** + * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_TEST_PREPARED + */ + struct GNUNET_MessageHeader header; +}; + +struct GNUNET_CMDS_ALL_LOCAL_TESTS_PREPARED +{ + /** + * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_LOCAL_TESTS_PREPARED + */ + struct GNUNET_MessageHeader header; +}; + GNUNET_NETWORK_STRUCT_END + #endif /* end of testing_cmds.h */ -- cgit v1.2.3