From 34e1c58cb39a649c9a4c551681cedf19807b85f0 Mon Sep 17 00:00:00 2001 From: t3sserakt Date: Wed, 7 Dec 2022 12:42:31 +0100 Subject: - added configuration to be able to start executables on a router node - added barrier functionality --- src/include/Makefile.am | 1 + src/include/gnunet_protocols.h | 8 + src/include/gnunet_testing_barrier.h | 272 +++++++++++++++++++++++++++++++ src/include/gnunet_testing_netjail_lib.h | 62 ++++--- src/include/gnunet_testing_ng_lib.h | 68 +++++++- src/include/gnunet_testing_plugin.h | 10 ++ 6 files changed, 395 insertions(+), 26 deletions(-) create mode 100644 src/include/gnunet_testing_barrier.h (limited to 'src/include') diff --git a/src/include/Makefile.am b/src/include/Makefile.am index bda1a012b..0f091b615 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am @@ -117,6 +117,7 @@ gnunetinclude_HEADERS = \ gnunet_strings_lib.h \ gnunet_testbed_service.h \ gnunet_testbed_logger_service.h \ + gnunet_testing_barrier.h \ gnunet_testing_lib.h \ gnunet_testing_plugin.h \ gnunet_testing_ng_lib.h \ diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 509c97fb2..8f857e86c 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h @@ -3601,6 +3601,14 @@ extern "C" { #define GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED 1706 +#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_REACHED 1707 + +#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_ATTACH 1708 + +#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_ADVANCED 1709 + +#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_ATTACHED 1710 + /*********************************************************************************/ /*********************************************************************************/ diff --git a/src/include/gnunet_testing_barrier.h b/src/include/gnunet_testing_barrier.h new file mode 100644 index 000000000..4a3d87ec7 --- /dev/null +++ b/src/include/gnunet_testing_barrier.h @@ -0,0 +1,272 @@ +/* + This file is part of GNUnet + Copyright (C) 2022 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 include/gnunet_testing_barrier.h + * @brief API to manage barriers. + * @author t3sserakt + */ + +#ifndef GNUNET_TESTING_BARRIER_LIB_H +#define GNUNET_TESTING_BARRIER_LIB_H + +#include "gnunet_testing_lib.h" +#include "gnunet_testing_netjail_lib.h" + +struct GNUNET_TESTING_Barrier +{ + /** + * Pointer to the previous prefix in the DLL. + */ + struct GNUNET_TESTING_Barrier *prev; + + /** + * Pointer to the next prefix in the DLL. + */ + struct GNUNET_TESTING_Barrier *next; + + /** + * Head of the DLL with local commands the barrier is attached too. + */ + struct GNUNET_TESTING_Command *cmds_head; + + /** + * Tail of the DLL with local commands the barrier is attached too. + */ + struct GNUNET_TESTING_Command *cmds_tail; + + /** + * Hash map containing the global known nodes which are not natted. + */ + struct GNUNET_CONTAINER_MultiShortmap *nodes; + + /** + * Name of the barrier. + */ + const char *name; + + /** + * Is this barrier running on the master. + */ + unsigned int running_on_master; + + /** + * Number of commands attached to this barrier. + */ + unsigned int expected_reaches; + + /** + * Number of commands which reached this barrier. + */ + unsigned int reached; + + /** + * Percentage of of commands which need to reach the barrier to change state. + * Can not be used together with to_be_reached; + */ + double percentage_to_be_reached; + + /** + * Number of commands which need to reach the barrier to change state. + * Can not be used together with percentage_to_be_reached; + */ + unsigned int number_to_be_reached; + + /* + * No barrier locally. Shadow created. Real barrier created elsewhere. + */ + unsigned int shadow; +}; + +/** + * Message send to a child loop to inform the child loop about a barrier being advanced. + */ +struct GNUNET_TESTING_CommandBarrierAdvanced +{ + /** + * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_ADVANCED + */ + struct GNUNET_MessageHeader header; + + /** + * The name of the barrier. + */ + const char *barrier_name; +}; + +/** + * Message send by a child loop to inform the master loop how much + * GNUNET_CMDS_BARRIER_REACHED messages the child will send. + */ +struct GNUNET_TESTING_CommandBarrierAttached +{ + /** + * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_ATTACHED + */ + struct GNUNET_MessageHeader header; + + /** + * The name of the barrier. + */ + const char *barrier_name; + + /** + * How often the child loop will reach the barrier. + */ + unsigned int expected_reaches; + + /** + * The number of the node the barrier is running on. + */ + unsigned int node_number; +}; + + +struct GNUNET_TESTING_CommandBarrierReached +{ + /** + * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_REACHED + */ + struct GNUNET_MessageHeader header; + + /** + * The name of the barrier. + */ + const char *barrier_name; + + /** + * The number of the node the barrier is reached. + */ + unsigned int node_number; + + /** + * The number of reach messages which most likely will send. + */ + unsigned int expected_number_of_reached_messages; +}; + + +/** + * Adding a node to the map of nodes of a barrier. + * + * @param nodes Map of nodes. + * @param node The node to add. + */ +void +GNUNET_TESTING_barrier_add_node (struct GNUNET_CONTAINER_MultiShortmap *nodes, + struct GNUNET_TESTING_NetjailNode *node); + + +struct GNUNET_TESTING_Command +GNUNET_TESTING_cmd_barrier_create ( + const char *label, + double percentage_to_be_reached, + unsigned int number_to_be_reached); + + +// Wait for barrier to be reached by all; +// async version implies reached but does not +// wait on other peers to reach it. +/** + * Create command. + * + * @param label name for command. + * @param barrier_label The name of the barrier we wait for and which will be reached. + * @param asynchronous_finish If GNUNET_YES this command will not block. Can be NULL. + * @param asynchronous_finish If GNUNET_YES this command will not block. Can be NULL. + * @param node_number The global numer of the node the cmd runs on. + * @param running_on_master Is this cmd running on the master loop. + * @param write_message Callback to write messages to the master loop. + * @return command. + */ +struct GNUNET_TESTING_Command +GNUNET_TESTING_cmd_barrier_reached ( + const char *label, + const char *barrier_label, + unsigned int asynchronous_finish, + unsigned int node_number, + unsigned int running_on_master, + TESTING_CMD_HELPER_write_cb write_message); + + +/** + * Can we advance the barrier? + * + * @param barrier The barrier in question. + * @return GNUNET_YES if we can advance the barrier, GNUNET_NO if not. + */ +unsigned int +GNUNET_TESTING_can_barrier_advance (struct GNUNET_TESTING_Barrier *barrier); + + +/** + * Send Message to netjail nodes that a barrier can be advanced. + * + * @param is The interpreter loop. + * @param barrier_name The name of the barrier to advance. + * @param global_node_number The global number of the node to inform. + */ +void +GNUNET_TESTING_send_barrier_advance (struct GNUNET_TESTING_Interpreter *is, + const char *barrier_name, + unsigned int global_node_number); + + +/** + * Finish all "barrier reached" comands attached to this barrier. + * + * @param barrier The barrier in question. + */ +void +GNUNET_TESTING_finish_attached_cmds (struct GNUNET_TESTING_Interpreter *is, + struct GNUNET_TESTING_Barrier *barrier); + + +/** + * Send Message to master loop that cmds being attached to a barrier. + * + * @param is The interpreter loop. + * @param barrier_name The name of the barrier to advance. + * @param subnet_number The number of the subnet. + * @param node_number The node to inform. + * @param write_message Callback to write messages to the master loop. + */ +void +GNUNET_TESTING_send_barrier_attach (struct GNUNET_TESTING_Interpreter *is, + char *barrier_name, + unsigned int global_node_number, + unsigned int expected_reaches, + TESTING_CMD_HELPER_write_cb write_message); + + +/** + * Getting a node from a map by global node number. + * + * @param nodes The map. + * @param node_number The global node number. + * @return The node. + */ +struct GNUNET_TESTING_NetjailNode * +GNUNET_TESTING_barrier_get_node (struct GNUNET_CONTAINER_MultiShortmap *nodes, + unsigned int node_number); + + +#endif +/* end of testing_barrier.h */ diff --git a/src/include/gnunet_testing_netjail_lib.h b/src/include/gnunet_testing_netjail_lib.h index f736e1b42..4f52f5af0 100644 --- a/src/include/gnunet_testing_netjail_lib.h +++ b/src/include/gnunet_testing_netjail_lib.h @@ -144,6 +144,16 @@ struct GNUNET_TESTING_NodeConnection */ struct GNUNET_TESTING_NetjailNode { + /** + * Head of the DLL with the connections which shall be established to other nodes. + */ + struct GNUNET_TESTING_NodeConnection *node_connections_head; + + /** + * Tail of the DLL with the connections which shall be established to other nodes. + */ + struct GNUNET_TESTING_NodeConnection *node_connections_tail; + /** * Plugin for the test case to be run on this node. */ @@ -165,19 +175,19 @@ struct GNUNET_TESTING_NetjailNode unsigned int node_n; /** - * The number of unintentional additional connections this node waits for. This overwrites the global additional_connects value. + * The overall number of the node in the whole test system. */ - unsigned int additional_connects; + unsigned int node_number; /** - * Head of the DLL with the connections which shall be established to other nodes. + * The number of unintentional additional connections this node waits for. This overwrites the global additional_connects value. */ - struct GNUNET_TESTING_NodeConnection *node_connections_head; + unsigned int additional_connects; /** - * Tail of the DLL with the connections which shall be established to other nodes. + * The number of cmds waiting for a specific barrier. */ - struct GNUNET_TESTING_NodeConnection *node_connections_tail; + unsigned int expected_reaches; }; @@ -275,6 +285,17 @@ GNUNET_TESTING_get_additional_connects (unsigned int num, struct GNUNET_TESTING_NetjailTopology * topology); +/** + * Get a node from the topology. + * + * @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_NetjailNode * +GNUNET_TESTING_get_node (unsigned int num, + struct GNUNET_TESTING_NetjailTopology *topology); + /** * Get the connections to other nodes for a specific node. @@ -322,6 +343,16 @@ GNUNET_TESTING_calculate_num (struct struct GNUNET_TESTING_NetjailTopology *topology); struct TestState { + /** + * The head of the DLL with barriers of the test case. + */ + struct GNUNET_TESTING_Barrier *barriers_head; + + /** + * The tail of the DLL with barriers of the test case. + */ + struct GNUNET_TESTING_Barrier *barriers_tail; + /** * Callback to write messages to the master loop. * @@ -479,25 +510,6 @@ struct GNUNET_MessageHeader * GNUNET_TESTING_send_local_test_finished_msg (); -struct GNUNET_TESTING_Command -GNUNET_TESTING_cmd_barrier_create ( - const char *label); - - -struct GNUNET_TESTING_Command -GNUNET_TESTING_cmd_barrier_setup_finished ( - const char *label); - - -// Wait for barrier to be reached by all; -// async version implies reached but does not -// wait on other peers to reach it. -struct GNUNET_TESTING_Command -GNUNET_TESTING_cmd_barrier_reached ( - const char *label, - const char *barrier_label); - - struct GNUNET_TESTING_Command GNUNET_TESTING_cmd_block_until_all_peers_started ( const char *label, diff --git a/src/include/gnunet_testing_ng_lib.h b/src/include/gnunet_testing_ng_lib.h index d810a5342..9a6c82d90 100644 --- a/src/include/gnunet_testing_ng_lib.h +++ b/src/include/gnunet_testing_ng_lib.h @@ -193,6 +193,16 @@ struct GNUNET_TESTING_Command */ struct GNUNET_TIME_Relative default_timeout; + /** + * Pointer to the previous command in the DLL. + */ + struct GNUNET_TESTING_Command *prev; + + /** + * Pointer to the next command in the DLL. + */ + struct GNUNET_TESTING_Command *next; + /** * How often did we try to execute this command? (In case it is a request * that is repated.) Note that a command must have some built-in retry @@ -362,8 +372,9 @@ typedef void * @param timeout how long to wait for each command to execute * @param rc function to call with the final result * @param rc_cls closure for @a rc + * @return The interpreter. */ -void +struct GNUNET_TESTING_Interpreter * GNUNET_TESTING_run (struct GNUNET_TESTING_Command *commands, struct GNUNET_TIME_Relative timeout, GNUNET_TESTING_ResultCallback rc, @@ -396,10 +407,65 @@ int GNUNET_TESTING_has_in_name (const char *prog, const char *marker); +/** + * Deleting all barriers create in the context of this interpreter. + * + * @param is The interpreter. + */ +void +GNUNET_TESTING_delete_barriers (struct GNUNET_TESTING_Interpreter *is); + + +/** + * Getting a barrier from the interpreter. + * + * @param is The interpreter. + * @param barrier_name The name of the barrier. + * @return The barrier. + */ +struct GNUNET_TESTING_Barrier * +GNUNET_TESTING_get_barrier (struct GNUNET_TESTING_Interpreter *is, + const char *barrier_name); + + +/** + * Add a barrier to the loop. + * + * @param is The interpreter. + * @param barrier The barrier to add. + */ +void +GNUNET_TESTING_barrier_add (struct GNUNET_TESTING_Interpreter *is, + struct GNUNET_TESTING_Barrier *barrier); + /* ************** Specific interpreter commands ************ */ +/** + * Adding a helper handle to the interpreter. + * + * @param is The interpreter. + * @param helper The helper handle. + */ +void +GNUNET_TESTING_add_netjail_helper (struct GNUNET_TESTING_Interpreter *is, + const struct GNUNET_HELPER_Handle *helper); + + +/** + * Send Message to netjail nodes that a barrier can be advanced. + * + * @param is The interpreter. + * @param global_node_number The node to inform. + * @param header The message to send. + */ +void +GNUNET_TESTING_send_message_to_netjail (struct GNUNET_TESTING_Interpreter *is, + unsigned int global_node_number, + struct GNUNET_MessageHeader *header); + + /** * Returns the actual running command. * diff --git a/src/include/gnunet_testing_plugin.h b/src/include/gnunet_testing_plugin.h index 9d0ef269d..28b505976 100644 --- a/src/include/gnunet_testing_plugin.h +++ b/src/include/gnunet_testing_plugin.h @@ -62,6 +62,12 @@ typedef void typedef void (*GNUNET_TESTING_PLUGIN_ALL_LOCAL_TESTS_PREPARED) (); +typedef void +(*GNUNET_TESTING_PLUGIN_BARRIER_ADVANCED) (const char *barrier_name); + +typedef struct GNUNET_TESTING_Barrier * +(*GNUNET_TESTING_PLUGIN_GET_WAITING_FOR_BARRIERS) (); + struct GNUNET_TESTING_PluginFunctions { @@ -70,11 +76,15 @@ struct GNUNET_TESTING_PluginFunctions */ void *cls; + GNUNET_TESTING_PLUGIN_BARRIER_ADVANCED barrier_advanced; + GNUNET_TESTING_PLUGIN_StartTestCase start_testcase; GNUNET_TESTING_PLUGIN_ALL_PEERS_STARTED all_peers_started; GNUNET_TESTING_PLUGIN_ALL_LOCAL_TESTS_PREPARED all_local_tests_prepared; + + GNUNET_TESTING_PLUGIN_GET_WAITING_FOR_BARRIERS get_waiting_for_barriers; }; #if 0 /* keep Emacsens' auto-indent happy */ -- cgit v1.2.3