aboutsummaryrefslogtreecommitdiff
path: root/src/testing
diff options
context:
space:
mode:
authort3sserakt <t3ss@posteo.de>2022-12-07 12:42:31 +0100
committert3sserakt <t3ss@posteo.de>2022-12-07 12:42:31 +0100
commit34e1c58cb39a649c9a4c551681cedf19807b85f0 (patch)
tree79ea7222958c3ae086b2b2367f22cb66936ad045 /src/testing
parent8804d3efd5bccce3a5d7638a5fcb33450ade2f07 (diff)
downloadgnunet-34e1c58cb39a649c9a4c551681cedf19807b85f0.tar.gz
gnunet-34e1c58cb39a649c9a4c551681cedf19807b85f0.zip
- added configuration to be able to start executables on a router node
- added barrier functionality
Diffstat (limited to 'src/testing')
-rw-r--r--src/testing/Makefile.am2
-rw-r--r--src/testing/gnunet-cmds-helper.c81
-rwxr-xr-xsrc/testing/netjail_core.sh260
-rwxr-xr-xsrc/testing/netjail_exec.sh14
-rwxr-xr-xsrc/testing/netjail_start.sh74
-rwxr-xr-xsrc/testing/netjail_stop.sh59
-rw-r--r--src/testing/testing.c25
-rw-r--r--src/testing/testing_api_cmd_barrier.c256
-rw-r--r--src/testing/testing_api_cmd_barrier_reached.c214
-rw-r--r--src/testing/testing_api_cmd_block_until_external_trigger.c2
-rw-r--r--src/testing/testing_api_cmd_local_test_prepared.c6
-rw-r--r--src/testing/testing_api_cmd_netjail_start_testsystem.c248
-rw-r--r--src/testing/testing_api_cmd_netjail_stop_testsystem.c2
-rw-r--r--src/testing/testing_api_cmd_send_peer_ready.c8
-rw-r--r--src/testing/testing_api_loop.c250
-rw-r--r--src/testing/testing_cmds.h64
16 files changed, 998 insertions, 567 deletions
diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am
index bcb45da70..3a4990db4 100644
--- a/src/testing/Makefile.am
+++ b/src/testing/Makefile.am
@@ -29,6 +29,8 @@ gnunet_cmds_helper_LDADD = $(XLIB) \
29 $(LTLIBINTL) $(Z_LIBS) 29 $(LTLIBINTL) $(Z_LIBS)
30 30
31libgnunettesting_la_SOURCES = \ 31libgnunettesting_la_SOURCES = \
32 testing_api_cmd_barrier.c \
33 testing_api_cmd_barrier_reached.c \
32 testing_api_cmd_end.c \ 34 testing_api_cmd_end.c \
33 testing_api_cmd_finish.c \ 35 testing_api_cmd_finish.c \
34 testing_api_cmd_local_test_finished.c \ 36 testing_api_cmd_local_test_finished.c \
diff --git a/src/testing/gnunet-cmds-helper.c b/src/testing/gnunet-cmds-helper.c
index 8114d156d..477c8c60f 100644
--- a/src/testing/gnunet-cmds-helper.c
+++ b/src/testing/gnunet-cmds-helper.c
@@ -43,12 +43,13 @@
43#include "gnunet_testing_netjail_lib.h" 43#include "gnunet_testing_netjail_lib.h"
44#include "testing_cmds.h" 44#include "testing_cmds.h"
45#include "gnunet_testing_plugin.h" 45#include "gnunet_testing_plugin.h"
46#include "gnunet_testing_barrier.h"
46#include <zlib.h> 47#include <zlib.h>
47 48
48 49
49/** 50/**
50 * Generic logging shortcut 51 * Generic logging shortcut
51testing_api_cmd_block_until_all_peers_started.c */ 52 */
52#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__) 53#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
53 54
54/** 55/**
@@ -65,58 +66,6 @@ testing_api_cmd_block_until_all_peers_started.c */
65struct GNUNET_SCHEDULER_Task *finished_task; 66struct GNUNET_SCHEDULER_Task *finished_task;
66 67
67/** 68/**
68 * Handle for a plugin.
69 */
70struct Plugin
71{
72 /**
73 * Name of the shared library.
74 */
75 char *library_name;
76
77 /**
78 * Plugin API.
79 */
80 struct GNUNET_TESTING_PluginFunctions *api;
81
82 /**
83 * IP address of the specific node the helper is running for.
84 *
85 */
86 char *node_ip;
87
88 /**
89 * Name of the test case plugin.
90 *
91 */
92 char *plugin_name;
93
94 /**
95 * The number of namespaces
96 *
97 */
98 char *global_n;
99
100 /**
101 * The number of local nodes per namespace.
102 *
103 */
104 char *local_m;
105
106 /**
107 * The number of the namespace this node is in.
108 *
109 */
110 char *n;
111
112 /**
113 * The number of the node in the namespace.
114 *
115 */
116 char *m;
117};
118
119/**
120 * Struct with information about a specific node and the whole network namespace setup. 69 * Struct with information about a specific node and the whole network namespace setup.
121 * 70 *
122 */ 71 */
@@ -371,8 +320,8 @@ tokenizer_cb (void *cls, const struct GNUNET_MessageHeader *message)
371{ 320{
372 321
373 struct NodeIdentifier *ni = cls; 322 struct NodeIdentifier *ni = cls;
374 const struct GNUNET_CMDS_HelperInit *msg; 323 const struct GNUNET_TESTING_CommandHelperInit *msg;
375 struct GNUNET_CMDS_HelperReply *reply; 324 struct GNUNET_TESTING_CommandHelperReply *reply;
376 char *binary; 325 char *binary;
377 char *plugin_name; 326 char *plugin_name;
378 size_t plugin_name_size; 327 size_t plugin_name_size;
@@ -390,9 +339,9 @@ tokenizer_cb (void *cls, const struct GNUNET_MessageHeader *message)
390 msize = ntohs (message->size); 339 msize = ntohs (message->size);
391 if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT == ntohs (message->type)) 340 if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT == ntohs (message->type))
392 { 341 {
393 msg = (const struct GNUNET_CMDS_HelperInit *) message; 342 msg = (const struct GNUNET_TESTING_CommandHelperInit *) message;
394 plugin_name_size = ntohs (msg->plugin_name_size); 343 plugin_name_size = ntohs (msg->plugin_name_size);
395 if ((sizeof(struct GNUNET_CMDS_HelperInit) + plugin_name_size) > msize) 344 if ((sizeof(struct GNUNET_TESTING_CommandHelperInit) + plugin_name_size) > msize)
396 { 345 {
397 GNUNET_break (0); 346 GNUNET_break (0);
398 LOG (GNUNET_ERROR_TYPE_WARNING, 347 LOG (GNUNET_ERROR_TYPE_WARNING,
@@ -445,8 +394,8 @@ tokenizer_cb (void *cls, const struct GNUNET_MessageHeader *message)
445 plugin->n, plugin->local_m, ni->topology_data, 394 plugin->n, plugin->local_m, ni->topology_data,
446 ni->read_file, &finished_cb); 395 ni->read_file, &finished_cb);
447 396
448 msg_length = sizeof(struct GNUNET_CMDS_HelperReply); 397 msg_length = sizeof(struct GNUNET_TESTING_CommandHelperReply);
449 reply = GNUNET_new (struct GNUNET_CMDS_HelperReply); 398 reply = GNUNET_new (struct GNUNET_TESTING_CommandHelperReply);
450 reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY); 399 reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY);
451 reply->header.size = htons ((uint16_t) msg_length); 400 reply->header.size = htons ((uint16_t) msg_length);
452 401
@@ -458,6 +407,14 @@ tokenizer_cb (void *cls, const struct GNUNET_MessageHeader *message)
458 407
459 return GNUNET_OK; 408 return GNUNET_OK;
460 } 409 }
410 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_ADVANCED == ntohs (
411 message->type))
412 {
413 struct GNUNET_TESTING_CommandBarrierAdvanced *adm = (struct GNUNET_TESTING_CommandBarrierAdvanced *) message;
414
415 plugin->api->barrier_advanced (adm->barrier_name);
416 return GNUNET_OK;
417 }
461 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED == ntohs ( 418 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED == ntohs (
462 message->type)) 419 message->type))
463 { 420 {
@@ -554,7 +511,8 @@ run (void *cls,
554{ 511{
555 struct NodeIdentifier *ni = cls; 512 struct NodeIdentifier *ni = cls;
556 513
557 LOG_DEBUG ("Starting interpreter loop helper...\n"); 514 LOG (GNUNET_ERROR_TYPE_DEBUG,
515 "Starting interpreter loop helper...\n");
558 516
559 tokenizer = GNUNET_MST_create (&tokenizer_cb, ni); 517 tokenizer = GNUNET_MST_create (&tokenizer_cb, ni);
560 stdin_fd = GNUNET_DISK_get_handle_from_native (stdin); 518 stdin_fd = GNUNET_DISK_get_handle_from_native (stdin);
@@ -564,6 +522,8 @@ run (void *cls,
564 &read_task, 522 &read_task,
565 NULL); 523 NULL);
566 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); 524 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
525 LOG (GNUNET_ERROR_TYPE_DEBUG,
526 "Interpreter loop helper started.\n");
567} 527}
568 528
569 529
@@ -662,6 +622,7 @@ main (int argc, char **argv)
662 } 622 }
663 shc_chld = 623 shc_chld =
664 GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, &sighandler_child_death); 624 GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, &sighandler_child_death);
625
665 ret = GNUNET_PROGRAM_run (argc, 626 ret = GNUNET_PROGRAM_run (argc,
666 argv, 627 argv,
667 "gnunet-cmds-helper", 628 "gnunet-cmds-helper",
diff --git a/src/testing/netjail_core.sh b/src/testing/netjail_core.sh
deleted file mode 100755
index ef0a54a5e..000000000
--- a/src/testing/netjail_core.sh
+++ /dev/null
@@ -1,260 +0,0 @@
1#!/bin/sh
2#
3
4
5PREFIX=${PPID:?must run from a parent process}
6
7# running with `sudo` is required to be
8# able running the actual commands as the
9# original user.
10
11export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
12
13export RESULT=
14export NAMESPACE_NUM=0
15export INTERFACE_NUM=0
16
17netjail_next_namespace() {
18 local NUM=$NAMESPACE_NUM
19 NAMESPACE_NUM=$(($NAMESPACE_NUM + 1))
20 RESULT=$NUM
21}
22
23netjail_next_interface() {
24 local NUM=$INTERFACE_NUM
25 INTERFACE_NUM=$(($INTERFACE_NUM + 1))
26 RESULT=$NUM
27}
28
29netjail_opt() {
30 local OPT=$1
31 shift 1
32
33 INDEX=1
34
35 while [ $# -gt 0 ]; do
36 if [ "$1" = "$OPT" ]; then
37 RESULT=$INDEX
38 return
39 fi
40
41 INDEX=$(($INDEX + 1))
42 shift 1
43 done
44
45 RESULT=0
46}
47
48netjail_opts() {
49 local OPT=$1
50 local DEF=$2
51 shift 2
52
53 while [ $# -gt 0 ]; do
54 if [ "$1" = "$OPT" ]; then
55 printf "$2"
56 return
57 fi
58
59 shift 1
60 done
61
62 RESULT="$DEF"
63}
64
65netjail_check() {
66 local NODE_COUNT=$1
67 local FD_COUNT=$(($(ls /proc/self/fd | wc -w) - 4))
68
69 # quit if `$FD_COUNT < ($LOCAL_M * $GLOBAL_N * 2)`:
70 # the script also requires `sudo -C ($FD_COUNT + 4)`
71 # so you need 'Defaults closefrom_override' in the
72 # sudoers file.
73
74 if [ $FD_COUNT -lt $(($NODE_COUNT * 2)) ]; then
75 echo "File descriptors do not match requirements!" >&2
76 exit 1
77 fi
78}
79
80netjail_check_bin() {
81 local PROGRAM=$1
82 local MATCH=$(ls $(echo $PATH | tr ":" "\n") | grep "^$PROGRAM\$" | tr "\n" " " | awk '{ print $1 }')
83
84 # quit if the required binary $PROGRAM can not be
85 # found in the used $PATH.
86
87 if [ "$MATCH" != "$PROGRAM" ]; then
88 echo "Required binary not found: $PROGRAM" >&2
89 exit 1
90 fi
91}
92
93netjail_bridge() {
94 netjail_next_interface
95 local NUM=$RESULT
96 local BRIDGE=$(printf "%06x-%08x" $PREFIX $NUM)
97
98 ip link add $BRIDGE type bridge
99 ip link set dev $BRIDGE up
100
101 RESULT=$BRIDGE
102}
103
104netjail_bridge_name() {
105 netjail_next_interface
106 local NUM=$RESULT
107 local BRIDGE=$(printf "%06x-%08x" $PREFIX $NUM)
108
109 RESULT=$BRIDGE
110}
111
112netjail_bridge_clear() {
113 local BRIDGE=$1
114
115 ip link delete $BRIDGE
116}
117
118netjail_node() {
119 netjail_next_namespace
120 local NUM=$RESULT
121 local NODE=$(printf "%06x-%08x" $PREFIX $NUM)
122
123 ip netns add $NODE
124
125 RESULT=$NODE
126}
127
128netjail_node_name() {
129 netjail_next_namespace
130 local NUM=$RESULT
131 local NODE=$(printf "%06x-%08x" $PREFIX $NUM)
132
133 RESULT=$NODE
134}
135
136netjail_node_clear() {
137 local NODE=$1
138
139 ip netns delete $NODE
140}
141
142netjail_node_link_bridge() {
143 local NODE=$1
144 local BRIDGE=$2
145 local ADDRESS=$3
146 local MASK=$4
147
148 netjail_next_interface
149 local NUM_IF=$RESULT
150 netjail_next_interface
151 local NUM_BR=$RESULT
152
153 local LINK_IF=$(printf "%06x-%08x" $PREFIX $NUM_IF)
154 local LINK_BR=$(printf "%06x-%08x" $PREFIX $NUM_BR)
155
156 ip link add $LINK_IF type veth peer name $LINK_BR
157 ip link set $LINK_IF netns $NODE
158 ip link set $LINK_BR master $BRIDGE
159
160 ip -n $NODE addr add "$ADDRESS/$MASK" dev $LINK_IF
161 ip -n $NODE link set $LINK_IF up
162 ip -n $NODE link set up dev lo
163
164 ip link set $LINK_BR up
165
166 RESULT=$LINK_BR
167}
168
169netjail_node_link_bridge_name() {
170
171 netjail_next_interface
172 netjail_next_interface
173 local NUM_BR=$RESULT
174
175 local LINK_BR=$(printf "%06x-%08x" $PREFIX $NUM_BR)
176
177 RESULT=$LINK_BR
178}
179
180netjail_node_unlink_bridge() {
181 local LINK_BR=$1
182
183 ip link delete $LINK_BR
184}
185
186netjail_node_add_nat() {
187 local NODE=$1
188 local ADDRESS=$2
189 local MASK=$3
190
191 ip netns exec $NODE iptables -t nat -A POSTROUTING -s "$ADDRESS/$MASK" -j MASQUERADE
192}
193
194netjail_node_add_default() {
195 local NODE=$1
196 local ADDRESS=$2
197
198 ip -n $NODE route add default via $ADDRESS
199}
200
201netjail_node_exec() {
202 JAILOR=${SUDO_USER:?must run in sudo}
203 local NODE=$1
204 local FD_IN=$2
205 local FD_OUT=$3
206 shift 3
207
208 ip netns exec $NODE sudo -u $JAILOR -- $@ 1>& $FD_OUT 0<& $FD_IN
209}
210
211netjail_node_exec_without_fds() {
212 JAILOR=${SUDO_USER:?must run in sudo}
213 NODE=$1
214 shift 1
215
216 ip netns exec $NODE sudo -u $JAILOR -- $@
217}
218
219netjail_node_exec_without_fds_and_sudo() {
220 NODE=$1
221 shift 1
222
223 ip netns exec $NODE $@
224}
225
226netjail_kill() {
227 local PID=$1
228 local MATCH=$(ps --pid $PID | awk "{ if ( \$1 == $PID ) { print \$1 } }" | wc -l)
229
230 if [ $MATCH -gt 0 ]; then
231 kill -n 19 $PID
232
233 for CHILD in $(ps -o pid,ppid -ax | awk "{ if ( \$2 == $PID ) { print \$1 } }"); do
234 netjail_kill $CHILD
235 done
236
237 kill $PID
238 fi
239}
240
241netjail_killall() {
242 if [ $# -gt 0 ]; then
243 local PIDS=$1
244
245 for PID in $PIDS; do
246 netjail_kill $PID
247 done
248 fi
249}
250
251netjail_waitall() {
252 if [ $# -gt 0 ]; then
253 local PIDS=$1
254
255 for PID in $PIDS; do
256 wait $PID
257 done
258 fi
259}
260
diff --git a/src/testing/netjail_exec.sh b/src/testing/netjail_exec.sh
deleted file mode 100755
index cd993a39b..000000000
--- a/src/testing/netjail_exec.sh
+++ /dev/null
@@ -1,14 +0,0 @@
1#!/bin/sh
2. "./../testing/netjail_core.sh"
3
4set -eu
5set -x
6
7export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
8
9M=$1
10N=$2
11
12NODE=$6
13
14netjail_node_exec_without_fds_and_sudo $NODE $3 $4 $5 $1 $2
diff --git a/src/testing/netjail_start.sh b/src/testing/netjail_start.sh
deleted file mode 100755
index 1dfe1dfdf..000000000
--- a/src/testing/netjail_start.sh
+++ /dev/null
@@ -1,74 +0,0 @@
1#!/bin/bash
2. "./../testing/netjail_core.sh"
3. "./../testing/topo.sh"
4
5set -eu
6set -x
7
8export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
9
10filename=$1
11PREFIX=$2
12
13read_topology $filename
14
15shift 2
16
17LOCAL_GROUP="192.168.15"
18GLOBAL_GROUP="92.68.150"
19KNOWN_GROUP="92.68.151"
20
21
22echo "Start [local: $LOCAL_GROUP.0/24, global: $GLOBAL_GROUP.0/16]"
23
24netjail_bridge
25NETWORK_NET=$RESULT
26
27for X in $(seq $KNOWN); do
28 netjail_node
29 KNOWN_NODES[$X]=$RESULT
30 netjail_node_link_bridge ${KNOWN_NODES[$X]} $NETWORK_NET "$KNOWN_GROUP.$X" 16
31 KNOWN_LINKS[$X]=$RESULT
32done
33
34declare -A NODES
35declare -A NODE_LINKS
36
37for N in $(seq $GLOBAL_N); do
38 netjail_node
39 ROUTERS[$N]=$RESULT
40 netjail_node_link_bridge ${ROUTERS[$N]} $NETWORK_NET "$GLOBAL_GROUP.$N" 16
41 NETWORK_LINKS[$N]=$RESULT
42 netjail_bridge
43 ROUTER_NETS[$N]=$RESULT
44
45 for M in $(seq $LOCAL_M); do
46 netjail_node
47 NODES[$N,$M]=$RESULT
48 netjail_node_link_bridge ${NODES[$N,$M]} ${ROUTER_NETS[$N]} "$LOCAL_GROUP.$M" 24
49 NODE_LINKS[$N,$M]=$RESULT
50 done
51
52 ROUTER_ADDR="$LOCAL_GROUP.$(($LOCAL_M+1))"
53 netjail_node_link_bridge ${ROUTERS[$N]} ${ROUTER_NETS[$N]} $ROUTER_ADDR 24
54 ROUTER_LINKS[$N]=$RESULT
55
56 netjail_node_add_nat ${ROUTERS[$N]} $ROUTER_ADDR 24
57
58 for M in $(seq $LOCAL_M); do
59 netjail_node_add_default ${NODES[$N,$M]} $ROUTER_ADDR
60 done
61
62 # TODO Topology configuration must be enhanced to configure forwarding to more than one subnet node via different ports.
63
64 if [ "1" == "${R_TCP[$N]}" ]
65 then
66 ip netns exec ${ROUTERS[$N]} iptables -t nat -A PREROUTING -p tcp -d $GLOBAL_GROUP.$N --dport 60002 -j DNAT --to $LOCAL_GROUP.1
67 ip netns exec ${ROUTERS[$N]} iptables -A FORWARD -d $LOCAL_GROUP.1 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
68 fi
69 if [ "1" == "${R_UDP[$N]}" ]
70 then
71 ip netns exec ${ROUTERS[$N]} iptables -t nat -A PREROUTING -p udp -d $GLOBAL_GROUP.$N --dport 60002 -j DNAT --to $LOCAL_GROUP.1
72 ip netns exec ${ROUTERS[$N]} iptables -A FORWARD -d $LOCAL_GROUP.1 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
73 fi
74done
diff --git a/src/testing/netjail_stop.sh b/src/testing/netjail_stop.sh
deleted file mode 100755
index abfaf3acf..000000000
--- a/src/testing/netjail_stop.sh
+++ /dev/null
@@ -1,59 +0,0 @@
1#!/bin/bash
2. "./../testing/netjail_core.sh"
3. "./../testing/topo.sh"
4
5set -eu
6set -x
7
8export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
9
10filename=$1
11PREFIX=$2
12
13read_topology $filename
14
15declare -A NODES
16declare -A NODE_LINKS
17
18netjail_bridge_name
19NETWORK_NET=$RESULT
20
21for X in $(seq $KNOWN); do
22 netjail_node_name
23 KNOWN_NODES[$X]=$RESULT
24 netjail_node_link_bridge_name
25 KNOWN_LINKS[$X]=$RESULT
26 netjail_node_unlink_bridge ${KNOWN_LINKS[$X]}
27 netjail_node_clear ${KNOWN_NODES[$X]}
28done
29
30for N in $(seq $GLOBAL_N); do
31 netjail_node_name
32 ROUTERS[$N]=$RESULT
33 netjail_node_link_bridge_name
34 NETWORK_LINKS[$N]=$RESULT
35 netjail_bridge_name
36 ROUTER_NETS[$N]=$RESULT
37 netjail_node_link_bridge_name
38 ROUTER_LINKS[$N]=$RESULT
39
40 netjail_node_unlink_bridge ${ROUTER_LINKS[$N]}
41
42 for M in $(seq $LOCAL_M); do
43 netjail_node_name
44 NODES[$N,$M]=$RESULT
45 netjail_node_link_bridge_name
46 NODE_LINKS[$N,$M]=$RESULT
47 netjail_node_unlink_bridge ${NODE_LINKS[$N,$M]}
48 netjail_node_clear ${NODES[$N,$M]}
49 done
50
51
52 netjail_bridge_clear ${ROUTER_NETS[$N]}
53 netjail_node_unlink_bridge ${NETWORK_LINKS[$N]}
54 netjail_node_clear ${ROUTERS[$N]}
55done
56
57netjail_bridge_clear $NETWORK_NET
58
59echo "Done"
diff --git a/src/testing/testing.c b/src/testing/testing.c
index d18197860..de6bc45f5 100644
--- a/src/testing/testing.c
+++ b/src/testing/testing.c
@@ -2136,6 +2136,27 @@ get_node_info (unsigned int num,
2136 GNUNET_free (hkey); 2136 GNUNET_free (hkey);
2137} 2137}
2138 2138
2139/**
2140 * Get a node from the topology.
2141 *
2142 * @param num The specific node we want the connections for.
2143 * @param topology The topology we get the connections from.
2144 * @return The connections of the node.
2145 */
2146struct GNUNET_TESTING_NetjailNode *
2147GNUNET_TESTING_get_node (unsigned int num,
2148 struct GNUNET_TESTING_NetjailTopology *topology)
2149{
2150 struct GNUNET_TESTING_NetjailNode *node;
2151 struct GNUNET_TESTING_NetjailNamespace *namespace;
2152 struct GNUNET_TESTING_NodeConnection *node_connections;
2153
2154 get_node_info (num, topology, &node, &namespace, &node_connections);
2155
2156 return node;
2157
2158}
2159
2139 2160
2140/** 2161/**
2141 * Get the connections to other nodes for a specific node. 2162 * Get the connections to other nodes for a specific node.
@@ -2208,7 +2229,7 @@ free_nodes_cb (void *cls,
2208 pos_connection); 2229 pos_connection);
2209 GNUNET_free (pos_connection); 2230 GNUNET_free (pos_connection);
2210 } 2231 }
2211 2232
2212 GNUNET_free (node->plugin); 2233 GNUNET_free (node->plugin);
2213 GNUNET_free (node); 2234 GNUNET_free (node);
2214 return GNUNET_OK; 2235 return GNUNET_OK;
@@ -2225,7 +2246,7 @@ free_namespaces_cb (void *cls,
2225 2246
2226 GNUNET_free (namespace->router); 2247 GNUNET_free (namespace->router);
2227 GNUNET_CONTAINER_multishortmap_iterate (namespace->nodes, free_nodes_cb, 2248 GNUNET_CONTAINER_multishortmap_iterate (namespace->nodes, free_nodes_cb,
2228 NULL); 2249 namespace->nodes);
2229 return GNUNET_OK; 2250 return GNUNET_OK;
2230 2251
2231} 2252}
diff --git a/src/testing/testing_api_cmd_barrier.c b/src/testing/testing_api_cmd_barrier.c
new file mode 100644
index 000000000..b0293f2c7
--- /dev/null
+++ b/src/testing/testing_api_cmd_barrier.c
@@ -0,0 +1,256 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2022 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file testing/testing_api_cmd_barrier.c
23 * @brief Barrier functionality.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_testing_ng_lib.h"
28#include "gnunet_testing_barrier.h"
29
30struct BarrierState
31{
32 /*
33 * Our barrier.
34 */
35 struct GNUNET_TESTING_Barrier *barrier;
36
37 /*
38 * Our label.
39 */
40 const char *label;
41};
42
43
44/**
45 * Send Message to master loop that cmds being attached to a barrier.
46 *
47 * @param is The interpreter loop.
48 * @param barrier_name The name of the barrier to advance.
49 * @param subnet_number The number of the subnet.
50 * @param node_number The node to inform.
51 * @param write_message Callback to write messages to the master loop.
52 */
53void
54GNUNET_TESTING_send_barrier_attach (struct GNUNET_TESTING_Interpreter *is,
55 char *barrier_name,
56 unsigned int global_node_number,
57 unsigned int expected_reaches,
58 TESTING_CMD_HELPER_write_cb write_message)
59{
60 struct GNUNET_TESTING_CommandBarrierAttached *atm = GNUNET_new (struct GNUNET_TESTING_CommandBarrierAttached);
61 size_t msg_length = sizeof(struct GNUNET_TESTING_CommandBarrierAttached);
62
63 atm->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_ATTACHED);
64 atm->header.size = htons ((uint16_t) msg_length);
65 atm->barrier_name = barrier_name;
66 atm->expected_reaches = expected_reaches;
67 atm->node_number = global_node_number;
68 write_message ((struct GNUNET_MessageHeader *) atm, msg_length);
69
70 GNUNET_free (atm);
71}
72
73
74/**
75 * Send Message to netjail nodes that a barrier can be advanced.
76 *
77 * @param is The interpreter loop.
78 * @param barrier_name The name of the barrier to advance.
79 * @param global_node_number The global number of the node to inform.
80 */
81void
82GNUNET_TESTING_send_barrier_advance (struct GNUNET_TESTING_Interpreter *is,
83 const char *barrier_name,
84 unsigned int global_node_number)
85{
86 struct GNUNET_TESTING_CommandBarrierAdvanced *adm = GNUNET_new (struct GNUNET_TESTING_CommandBarrierAdvanced);
87 size_t msg_length = sizeof(struct GNUNET_TESTING_CommandBarrierAdvanced);
88
89 adm->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_ADVANCED);
90 adm->header.size = htons ((uint16_t) msg_length);
91 adm->barrier_name = barrier_name;
92 GNUNET_TESTING_send_message_to_netjail (is,
93 global_node_number,
94 &adm->header);
95 GNUNET_free (adm);
96}
97
98
99/**
100 * Can we advance the barrier?
101 *
102 * @param barrier The barrier in question.
103 * @return GNUNET_YES if we can advance the barrier, GNUNET_NO if not.
104 */
105unsigned int
106GNUNET_TESTING_can_barrier_advance (struct GNUNET_TESTING_Barrier *barrier)
107{
108 unsigned int expected_reaches = barrier->expected_reaches;
109 unsigned int reached = barrier->reached;
110 double percentage_to_be_reached = barrier->percentage_to_be_reached;
111 unsigned int number_to_be_reached = barrier->number_to_be_reached;
112
113 if ((0 < percentage_to_be_reached &&
114 (double)expected_reaches/reached*100) >= percentage_to_be_reached ||
115 (0 < number_to_be_reached && reached >= number_to_be_reached ))
116 {
117 return GNUNET_YES;
118 }
119 else
120 {
121 return GNUNET_NO;
122 }
123}
124
125
126/**
127 * Offer internal data from a "barrier" CMD, to other commands.
128 *
129 * @param cls closure.
130 * @param[out] ret result.
131 * @param trait name of the trait.
132 * @param index index number of the object to offer.
133 * @return #GNUNET_OK on success.
134 */
135static enum GNUNET_GenericReturnValue
136barrier_traits (void *cls,
137 const void **ret,
138 const char *trait,
139 unsigned int index)
140{
141 struct BarrierState *bs = cls;
142
143 struct GNUNET_TESTING_Trait traits[] = {
144 GNUNET_TESTING_trait_end ()
145 };
146
147 /* Always return current command. */
148 return GNUNET_TESTING_get_trait (traits,
149 ret,
150 trait,
151 index);
152}
153
154/**
155 * Cleanup the state from a "barrier" CMD, and possibly
156 * cancel a pending operation thereof.
157 *
158 * @param cls closure.
159 */
160static void
161barrier_cleanup (void *cls)
162{
163 struct BarrierState *brs = cls;
164
165 GNUNET_free (brs->barrier);
166 GNUNET_free (brs);
167}
168
169/**
170 * Run the command.
171 *
172 * @param cls closure.
173 * @param is the interpreter state.
174 */
175static void
176barrier_run (void *cls,
177 struct GNUNET_TESTING_Interpreter *is)
178{
179 struct BarrierState *brs = cls;
180
181 GNUNET_TESTING_barrier_add (is, brs->barrier);
182}
183
184/**
185 * Adding a node to the map of nodes of a barrier.
186 *
187 * @param nodes Map of nodes.
188 * @param node The node to add.
189 */
190void
191GNUNET_TESTING_barrier_add_node (struct GNUNET_CONTAINER_MultiShortmap *nodes,
192 struct GNUNET_TESTING_NetjailNode *node)
193{
194 struct GNUNET_HashCode hc;
195 struct GNUNET_ShortHashCode key;
196
197 GNUNET_CRYPTO_hash (&(node->node_number), sizeof(node->node_number), &hc);
198 memcpy (&key, &hc, sizeof (key));
199 GNUNET_CONTAINER_multishortmap_put (nodes,
200 &key,
201 node,
202 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
203}
204
205
206/**
207 * Getting a node from a map by global node number.
208 *
209 * @param nodes The map.
210 * @param node_number The global node number.
211 * @return The node.
212 */
213struct GNUNET_TESTING_NetjailNode *
214GNUNET_TESTING_barrier_get_node (struct GNUNET_CONTAINER_MultiShortmap *nodes,
215 unsigned int node_number)
216{
217 struct GNUNET_HashCode hc;
218 struct GNUNET_ShortHashCode *key;
219
220 GNUNET_CRYPTO_hash (&(node_number), sizeof(node_number), &hc);
221 memcpy (&key,
222 &hc,
223 sizeof (key));
224 return GNUNET_CONTAINER_multishortmap_get (nodes, key);
225}
226
227
228struct GNUNET_TESTING_Command
229GNUNET_TESTING_cmd_barrier_create (const char *label,
230 double percentage_to_be_reached,
231 unsigned int number_to_be_reached)
232{
233 struct GNUNET_TESTING_Barrier *barrier;
234 struct BarrierState *bs;
235
236 bs = GNUNET_new (struct BarrierState);
237 bs->label = label;
238 barrier = GNUNET_new (struct GNUNET_TESTING_Barrier);
239 barrier->name = label;
240 GNUNET_assert (0 < percentage_to_be_reached && 0 == number_to_be_reached ||
241 0 == percentage_to_be_reached && 0 < number_to_be_reached);
242 barrier->percentage_to_be_reached;
243 barrier->number_to_be_reached;
244 bs->barrier = barrier;
245 {
246 struct GNUNET_TESTING_Command cmd = {
247 .cls = bs,
248 .label = label,
249 .run = &barrier_run,
250 .cleanup = &barrier_cleanup,
251 .traits = &barrier_traits
252 };
253
254 return cmd;
255 }
256}
diff --git a/src/testing/testing_api_cmd_barrier_reached.c b/src/testing/testing_api_cmd_barrier_reached.c
new file mode 100644
index 000000000..7e6f58fc1
--- /dev/null
+++ b/src/testing/testing_api_cmd_barrier_reached.c
@@ -0,0 +1,214 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2022 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file testing/testing_api_cmd_barrier_reached.c
23 * @brief Command to signal barrier was reached.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_testing_ng_lib.h"
28#include "gnunet_testing_barrier.h"
29
30/**
31 * Struct with information for callbacks.
32 *
33 */
34struct BarrierReachedState
35{
36 /**
37 * Callback to write messages to the master loop.
38 *
39 */
40 TESTING_CMD_HELPER_write_cb write_message;
41
42 /**
43 * Context for our asynchronous completion.
44 */
45 struct GNUNET_TESTING_AsyncContext ac;
46
47 /**
48 * The label of this command.
49 */
50 const char *label;
51
52 /**
53 * The name of the barrier this commands wait (if finishing asynchronous) for or/and reaches.
54 */
55 const char *barrier_name;
56
57 /*
58 * The global numer of the node the cmd runs on.
59 */
60 unsigned int node_number;
61
62 /**
63 * If this command will block.
64 */
65 unsigned int asynchronous_finish;
66
67 /**
68 * Is this cmd running on the master loop.
69 */
70 unsigned int running_on_master;
71};
72
73
74/**
75 * Run the command.
76 *
77 * @param cls closure.
78 * @param is the interpreter state.
79 */
80static void
81barrier_reached_run (void *cls,
82 struct GNUNET_TESTING_Interpreter *is)
83{
84 struct BarrierReachedState *brs = cls;
85 struct GNUNET_TESTING_Barrier *barrier;
86 struct GNUNET_TESTING_Command *cmd;
87 size_t msg_length;
88 struct GNUNET_TESTING_CommandBarrierReached *msg;
89
90 barrier = GNUNET_TESTING_get_barrier (is, brs->barrier_name);
91 if (NULL == barrier)
92 {
93 barrier = GNUNET_new (struct GNUNET_TESTING_Barrier);
94 barrier->shadow = GNUNET_YES;
95 barrier->name = brs->label;
96 GNUNET_TESTING_barrier_add (is, barrier);
97 }
98 barrier->reached++;
99 if (GNUNET_TESTING_can_barrier_advance (barrier))
100 {
101 cmd->asynchronous_finish = GNUNET_YES;
102 GNUNET_TESTING_finish_attached_cmds (is, barrier);
103 }
104 else if (GNUNET_NO == brs->asynchronous_finish)
105 {
106 cmd = GNUNET_TESTING_interpreter_get_current_command (is);
107 GNUNET_CONTAINER_DLL_insert (barrier->cmds_head,
108 barrier->cmds_tail,
109 cmd);
110 }
111 else
112 {
113 cmd->asynchronous_finish = GNUNET_YES;
114 }
115 if (GNUNET_NO == brs->running_on_master)
116 {
117 msg_length = sizeof(struct GNUNET_TESTING_CommandBarrierReached);
118 msg = GNUNET_new (struct GNUNET_TESTING_CommandBarrierReached);
119 msg->header.size = htons ((uint16_t) msg_length);
120 msg->header.type = htons(GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_REACHED);
121 msg->barrier_name = barrier->name;
122 msg->node_number = brs->node_number;
123 brs->write_message ((struct GNUNET_MessageHeader *) msg, msg_length);
124 }
125}
126
127
128/**
129 * Cleanup the state from a "barrier reached" CMD, and possibly
130 * cancel a pending operation thereof.
131 *
132 * @param cls closure.
133 */
134static void
135barrier_reached_cleanup (void *cls)
136{
137 struct BarrierReachedState *brs = cls;
138
139 GNUNET_free (brs);
140}
141
142
143/**
144 * Offer internal data from a "batch" CMD, to other commands.
145 *
146 * @param cls closure.
147 * @param[out] ret result.
148 * @param trait name of the trait.
149 * @param index index number of the object to offer.
150 * @return #GNUNET_OK on success.
151 */
152static enum GNUNET_GenericReturnValue
153barrier_reached_traits (void *cls,
154 const void **ret,
155 const char *trait,
156 unsigned int index)
157{
158 struct BarrierReachedState *brs = cls;
159 struct GNUNET_TESTING_AsyncContext *ac = &brs->ac;
160
161 struct GNUNET_TESTING_Trait traits[] = {
162 GNUNET_TESTING_make_trait_async_context ((const void *) ac),
163 GNUNET_TESTING_trait_end ()
164 };
165
166 return GNUNET_TESTING_get_trait (traits,
167 ret,
168 trait,
169 index);
170}
171
172
173/**
174 * Create command.
175 *
176 * @param label name for command.
177 * @param barrier_label The name of the barrier we wait for (if finishing asynchronous) and which will be reached.
178 * @param asynchronous_finish If GNUNET_YES this command will not block. Can be NULL.
179 * @param node_number The global numer of the node the cmd runs on.
180 * @param running_on_master Is this cmd running on the master loop.
181 * @param write_message Callback to write messages to the master loop.
182 * @return command.
183 */
184struct GNUNET_TESTING_Command
185GNUNET_TESTING_cmd_barrier_reached (
186 const char *label,
187 const char *barrier_label,
188 unsigned int asynchronous_finish,
189 unsigned int node_number,
190 unsigned int running_on_master,
191 TESTING_CMD_HELPER_write_cb write_message)
192{
193 struct BarrierReachedState *brs;
194
195 brs = GNUNET_new (struct BarrierReachedState);
196 brs->label = label;
197 brs->barrier_name = barrier_label;
198 brs->asynchronous_finish = asynchronous_finish;
199 brs->node_number = node_number;
200 brs->running_on_master = running_on_master;
201 brs->write_message = write_message;
202 {
203 struct GNUNET_TESTING_Command cmd = {
204 .cls = brs,
205 .label = label,
206 .run = &barrier_reached_run,
207 .ac = &brs->ac,
208 .cleanup = &barrier_reached_cleanup,
209 .traits = &barrier_reached_traits
210 };
211
212 return cmd;
213 }
214}
diff --git a/src/testing/testing_api_cmd_block_until_external_trigger.c b/src/testing/testing_api_cmd_block_until_external_trigger.c
index f51b2109b..347791b7a 100644
--- a/src/testing/testing_api_cmd_block_until_external_trigger.c
+++ b/src/testing/testing_api_cmd_block_until_external_trigger.c
@@ -97,8 +97,6 @@ block_until_all_peers_started_run (void *cls,
97 * Create command. 97 * Create command.
98 * 98 *
99 * @param label name for command. 99 * @param label name for command.
100 * @param all_peers_started Flag which will be set from outside.
101 * @param asynchronous_finish If GNUNET_YES this command will not block. Can be NULL.
102 * @return command. 100 * @return command.
103 */ 101 */
104struct GNUNET_TESTING_Command 102struct GNUNET_TESTING_Command
diff --git a/src/testing/testing_api_cmd_local_test_prepared.c b/src/testing/testing_api_cmd_local_test_prepared.c
index e71d3ef45..0b88586e8 100644
--- a/src/testing/testing_api_cmd_local_test_prepared.c
+++ b/src/testing/testing_api_cmd_local_test_prepared.c
@@ -80,11 +80,11 @@ local_test_prepared_run (void *cls,
80{ 80{
81 struct LocalPreparedState *lfs = cls; 81 struct LocalPreparedState *lfs = cls;
82 82
83 struct GNUNET_CMDS_LOCAL_TEST_PREPARED *reply; 83 struct GNUNET_TESTING_CommandLocalTestPrepared *reply;
84 size_t msg_length; 84 size_t msg_length;
85 85
86 msg_length = sizeof(struct GNUNET_CMDS_LOCAL_TEST_PREPARED); 86 msg_length = sizeof(struct GNUNET_TESTING_CommandLocalTestPrepared);
87 reply = GNUNET_new (struct GNUNET_CMDS_LOCAL_TEST_PREPARED); 87 reply = GNUNET_new (struct GNUNET_TESTING_CommandLocalTestPrepared);
88 reply->header.type = htons ( 88 reply->header.type = htons (
89 GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_TEST_PREPARED); 89 GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_TEST_PREPARED);
90 reply->header.size = htons ((uint16_t) msg_length); 90 reply->header.size = htons ((uint16_t) msg_length);
diff --git a/src/testing/testing_api_cmd_netjail_start_testsystem.c b/src/testing/testing_api_cmd_netjail_start_testsystem.c
index 98de0698a..4b2fbcc56 100644
--- a/src/testing/testing_api_cmd_netjail_start_testsystem.c
+++ b/src/testing/testing_api_cmd_netjail_start_testsystem.c
@@ -27,6 +27,7 @@
27#include "gnunet_testing_ng_lib.h" 27#include "gnunet_testing_ng_lib.h"
28#include "gnunet_testing_netjail_lib.h" 28#include "gnunet_testing_netjail_lib.h"
29#include "testing_cmds.h" 29#include "testing_cmds.h"
30#include "gnunet_testing_barrier.h"
30 31
31#define NETJAIL_EXEC_SCRIPT "netjail_exec.sh" 32#define NETJAIL_EXEC_SCRIPT "netjail_exec.sh"
32 33
@@ -167,12 +168,17 @@ struct NetJailState
167}; 168};
168 169
169/** 170/**
170 * Struct containing the number of the test environment and the NetJailState which 171 * Struct containing the number of the netjail node and the NetJailState which
171 * will be handed to callbacks specific to a test environment. 172 * will be handed to callbacks specific to a test environment.
172 */ 173 */
173struct TestingSystemCount 174struct TestingSystemCount
174{ 175{
175 /** 176 /**
177 * The plugin correlated to this netjail node.
178 */
179 struct Plugin *plugin;
180
181 /**
176 * Kept in a DLL. 182 * Kept in a DLL.
177 */ 183 */
178 struct TestingSystemCount *next; 184 struct TestingSystemCount *next;
@@ -188,12 +194,6 @@ struct TestingSystemCount
188 struct GNUNET_HELPER_SendHandle *shandle; 194 struct GNUNET_HELPER_SendHandle *shandle;
189 195
190 /** 196 /**
191 * The number of the test environment.
192 *
193 */
194 unsigned int count;
195
196 /**
197 * Struct to store information handed over to callbacks. 197 * Struct to store information handed over to callbacks.
198 * 198 *
199 */ 199 */
@@ -214,7 +214,7 @@ static void
214netjail_exec_cleanup (void *cls) 214netjail_exec_cleanup (void *cls)
215{ 215{
216 struct NetJailState *ns = cls; 216 struct NetJailState *ns = cls;
217 217 GNUNET_TESTING_delete_barriers (ns->is);
218 GNUNET_free (ns); 218 GNUNET_free (ns);
219} 219}
220 220
@@ -259,10 +259,10 @@ clear_msg (void *cls, int result)
259 struct TestingSystemCount *tbc = cls; 259 struct TestingSystemCount *tbc = cls;
260 260
261 GNUNET_assert (NULL != tbc->shandle); 261 GNUNET_assert (NULL != tbc->shandle);
262 /*GNUNET_free (tbc->shandle); 262 //GNUNET_free (tbc->shandle);
263 tbc->shandle = NULL;*/ 263 GNUNET_free (tbc->plugin);
264 GNUNET_free (tbc->msg); 264 tbc->shandle = NULL;
265 tbc->msg = NULL; 265 GNUNET_free (tbc);
266} 266}
267 267
268 268
@@ -276,19 +276,19 @@ send_message_to_locals (
276{ 276{
277 const struct GNUNET_HELPER_Handle *helper; 277 const struct GNUNET_HELPER_Handle *helper;
278 struct TestingSystemCount *tbc; 278 struct TestingSystemCount *tbc;
279 unsigned int count;
279 280
280 LOG (GNUNET_ERROR_TYPE_DEBUG, 281 LOG (GNUNET_ERROR_TYPE_DEBUG,
281 "send message of type %u to locals\n", 282 "send message of type %u to locals\n",
282 header->type); 283 header->type);
283 tbc = GNUNET_new (struct TestingSystemCount); 284 tbc = GNUNET_new (struct TestingSystemCount);
284 tbc->ns = ns; 285 tbc->ns = ns;
285 // 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.
286 if (0 == i) 286 if (0 == i)
287 tbc->count = j; // + total_number; 287 count = j;
288 else 288 else
289 tbc->count = (i - 1) * ns->local_m + j + ns->known; // + total_number ; 289 count = (i - 1) * ns->local_m + j + ns->known;
290 290
291 helper = ns->helper[tbc->count - 1];// - total_number]; 291 helper = ns->helper[count - 1];
292 292
293 293
294 294
@@ -304,15 +304,32 @@ send_message_to_locals (
304 304
305 305
306static void 306static void
307send_barrier_advanced (struct GNUNET_TESTING_CommandBarrierReached *rm,
308 unsigned int i,
309 unsigned int j,
310 struct NetJailState *ns)
311{
312 struct GNUNET_TESTING_CommandBarrierAdvanced *adm = GNUNET_new (struct GNUNET_TESTING_CommandBarrierAdvanced);
313 size_t msg_length = sizeof(struct GNUNET_TESTING_CommandAllLocalTestsPrepared);
314
315 adm->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED);
316 adm->header.size = htons ((uint16_t) msg_length);
317 adm->barrier_name = rm->barrier_name;
318 send_message_to_locals (i, j, ns, &adm->header);
319 GNUNET_free (adm);
320}
321
322
323static void
307send_all_local_tests_prepared (unsigned int i, unsigned int j, struct 324send_all_local_tests_prepared (unsigned int i, unsigned int j, struct
308 NetJailState *ns) 325 NetJailState *ns)
309{ 326{
310 struct GNUNET_CMDS_ALL_LOCAL_TESTS_PREPARED *reply; 327 struct GNUNET_TESTING_CommandAllLocalTestsPrepared *reply;
311 size_t msg_length; 328 size_t msg_length;
312 329
313 330
314 msg_length = sizeof(struct GNUNET_CMDS_ALL_LOCAL_TESTS_PREPARED); 331 msg_length = sizeof(struct GNUNET_TESTING_CommandAllLocalTestsPrepared);
315 reply = GNUNET_new (struct GNUNET_CMDS_ALL_LOCAL_TESTS_PREPARED); 332 reply = GNUNET_new (struct GNUNET_TESTING_CommandAllLocalTestsPrepared);
316 reply->header.type = htons ( 333 reply->header.type = htons (
317 GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_LOCAL_TESTS_PREPARED); 334 GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_LOCAL_TESTS_PREPARED);
318 reply->header.size = htons ((uint16_t) msg_length); 335 reply->header.size = htons ((uint16_t) msg_length);
@@ -325,13 +342,11 @@ send_all_local_tests_prepared (unsigned int i, unsigned int j, struct
325static void 342static void
326send_all_peers_started (unsigned int i, unsigned int j, struct NetJailState *ns) 343send_all_peers_started (unsigned int i, unsigned int j, struct NetJailState *ns)
327{ 344{
328 345 struct GNUNET_TESTING_CommandAllPeersStarted *reply;
329 struct GNUNET_CMDS_ALL_PEERS_STARTED *reply;
330 size_t msg_length; 346 size_t msg_length;
331 347
332 348 msg_length = sizeof(struct GNUNET_TESTING_CommandAllPeersStarted);
333 msg_length = sizeof(struct GNUNET_CMDS_ALL_PEERS_STARTED); 349 reply = GNUNET_new (struct GNUNET_TESTING_CommandAllPeersStarted);
334 reply = GNUNET_new (struct GNUNET_CMDS_ALL_PEERS_STARTED);
335 reply->header.type = htons ( 350 reply->header.type = htons (
336 GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED); 351 GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED);
337 reply->header.size = htons ((uint16_t) msg_length); 352 reply->header.size = htons ((uint16_t) msg_length);
@@ -341,6 +356,44 @@ send_all_peers_started (unsigned int i, unsigned int j, struct NetJailState *ns)
341} 356}
342 357
343 358
359void
360barrier_attached (struct NetJailState *ns, const struct GNUNET_MessageHeader *message)
361{
362 struct GNUNET_TESTING_CommandBarrierAttached *am;
363 struct GNUNET_TESTING_NetjailNode *node;
364 struct GNUNET_TESTING_Barrier *barrier;
365
366 am = (struct GNUNET_TESTING_CommandBarrierAttached *) message;
367 barrier = GNUNET_TESTING_get_barrier (ns->is, am->barrier_name);
368 GNUNET_assert (NULL != barrier && GNUNET_NO == barrier->shadow);
369 node = GNUNET_TESTING_barrier_get_node (barrier->nodes, am->node_number);
370 if (NULL == node)
371 {
372 node = GNUNET_new (struct GNUNET_TESTING_NetjailNode);
373 node->node_number = am->node_number;
374 GNUNET_TESTING_barrier_add_node (barrier->nodes, node);
375 }
376 node->expected_reaches = node->expected_reaches + am->expected_reaches;
377 barrier->expected_reaches = barrier->expected_reaches + am->expected_reaches;
378}
379
380
381void
382barrier_reached (struct NetJailState *ns, const struct GNUNET_MessageHeader *message)
383{
384 struct GNUNET_TESTING_CommandBarrierReached *rm = (struct GNUNET_TESTING_CommandBarrierReached *) message;
385 struct GNUNET_TESTING_Barrier *barrier = GNUNET_TESTING_get_barrier (ns->is, rm->barrier_name);
386 struct GNUNET_TESTING_NetjailNode *node;
387
388 GNUNET_assert (NULL != barrier && GNUNET_NO == barrier->shadow);
389 barrier->reached++;
390 if (GNUNET_TESTING_can_barrier_advance (barrier))
391 {
392 GNUNET_TESTING_finish_attached_cmds (ns->is, barrier);
393 }
394}
395
396
344/** 397/**
345 * Functions with this signature are called whenever a 398 * Functions with this signature are called whenever a
346 * complete message is received by the tokenizer. 399 * complete message is received by the tokenizer.
@@ -356,63 +409,68 @@ send_all_peers_started (unsigned int i, unsigned int j, struct NetJailState *ns)
356static int 409static int
357helper_mst (void *cls, const struct GNUNET_MessageHeader *message) 410helper_mst (void *cls, const struct GNUNET_MessageHeader *message)
358{ 411{
359 // struct TestingSystemCount *tbc = cls;
360 struct NetJailState *ns = cls; 412 struct NetJailState *ns = cls;
361 unsigned int total_number = ns->local_m * ns->global_n + ns->known; 413 unsigned int total_number = ns->local_m * ns->global_n + ns->known;
362 uint16_t message_type = ntohs (message->type); 414 uint16_t message_type = ntohs (message->type);
363 415
364 switch (message_type) 416 switch (message_type)
365 { 417 {
366 case GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY: 418 case GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_ATTACHED:
367 ns->number_of_testsystems_started++; 419 barrier_attached (ns, message);
368 break; 420 break;
369 case GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED: 421 case GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_REACHED:
370 ns->number_of_peers_started++; 422 barrier_reached (ns, message);
371 if (ns->number_of_peers_started == total_number) 423 break;
372 { 424 case GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY:
373 for (int i = 1; i <= ns->known; i++) 425 ns->number_of_testsystems_started++;
374 { 426 break;
375 send_all_peers_started (0,i, ns); 427 case GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED:
376 } 428 ns->number_of_peers_started++;
377 for (int i = 1; i <= ns->global_n; i++) 429 if (ns->number_of_peers_started == total_number)
378 { 430 {
379 for (int j = 1; j <= ns->local_m; j++) 431 for (int i = 1; i <= ns->known; i++)
432 {
433 send_all_peers_started (0,i, ns);
434 }
435 for (int i = 1; i <= ns->global_n; i++)
380 { 436 {
381 send_all_peers_started (i,j, ns); 437 for (int j = 1; j <= ns->local_m; j++)
438 {
439 send_all_peers_started (i,j, ns);
440 }
382 } 441 }
442 ns->number_of_peers_started = 0;
383 } 443 }
384 ns->number_of_peers_started = 0; 444 break;
385 } 445 case GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_TEST_PREPARED:
386 break; 446 ns->number_of_local_tests_prepared++;
387 case GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_TEST_PREPARED: 447 if (ns->number_of_local_tests_prepared == total_number)
388 ns->number_of_local_tests_prepared++;
389 if (ns->number_of_local_tests_prepared == total_number)
390 {
391 for (int i = 1; i <= ns->known; i++)
392 { 448 {
393 send_all_local_tests_prepared (0,i, ns); 449 for (int i = 1; i <= ns->known; i++)
394 } 450 {
451 send_all_local_tests_prepared (0,i, ns);
452 }
395 453
396 for (int i = 1; i <= ns->global_n; i++) 454 for (int i = 1; i <= ns->global_n; i++)
397 {
398 for (int j = 1; j <= ns->local_m; j++)
399 { 455 {
400 send_all_local_tests_prepared (i,j, ns); 456 for (int j = 1; j <= ns->local_m; j++)
457 {
458 send_all_local_tests_prepared (i,j, ns);
459 }
401 } 460 }
402 } 461 }
403 } 462 break;
404 break; 463 case GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED:
405 case GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED: 464 ns->number_of_local_tests_finished++;
406 ns->number_of_local_tests_finished++; 465 if (ns->number_of_local_tests_finished == total_number)
407 if (ns->number_of_local_tests_finished == total_number) 466 {
408 { 467 GNUNET_SCHEDULER_cancel (ns->timeout_task);
409 GNUNET_SCHEDULER_cancel (ns->timeout_task); 468 GNUNET_TESTING_async_finish (&ns->ac);
410 GNUNET_TESTING_async_finish (&ns->ac); 469 }
411 } 470 break;
412 break; 471 default:
413 default: 472 // We received a message we can not handle.
414 // We received a message we can not handle. 473 GNUNET_assert (0);
415 GNUNET_assert (0);
416 } 474 }
417 475
418 LOG (GNUNET_ERROR_TYPE_DEBUG, 476 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -454,16 +512,16 @@ exp_cb (void *cls)
454 * @param plugin_name Name of the test case plugin the helper will load. 512 * @param plugin_name Name of the test case plugin the helper will load.
455 * 513 *
456 */ 514 */
457static struct GNUNET_CMDS_HelperInit * 515static struct GNUNET_TESTING_CommandHelperInit *
458create_helper_init_msg_ (const char *plugin_name) 516create_helper_init_msg_ (const char *plugin_name)
459{ 517{
460 struct GNUNET_CMDS_HelperInit *msg; 518 struct GNUNET_TESTING_CommandHelperInit *msg;
461 uint16_t plugin_name_len; 519 uint16_t plugin_name_len;
462 uint16_t msg_size; 520 uint16_t msg_size;
463 521
464 GNUNET_assert (NULL != plugin_name); 522 GNUNET_assert (NULL != plugin_name);
465 plugin_name_len = strlen (plugin_name); 523 plugin_name_len = strlen (plugin_name);
466 msg_size = sizeof(struct GNUNET_CMDS_HelperInit) + plugin_name_len; 524 msg_size = sizeof(struct GNUNET_TESTING_CommandHelperInit) + plugin_name_len;
467 msg = GNUNET_malloc (msg_size); 525 msg = GNUNET_malloc (msg_size);
468 msg->header.size = htons (msg_size); 526 msg->header.size = htons (msg_size);
469 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT); 527 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT);
@@ -484,8 +542,9 @@ start_helper (struct NetJailState *ns,
484 unsigned int m, 542 unsigned int m,
485 unsigned int n) 543 unsigned int n)
486{ 544{
545 struct Plugin *plugin;
487 struct GNUNET_HELPER_Handle *helper; 546 struct GNUNET_HELPER_Handle *helper;
488 struct GNUNET_CMDS_HelperInit *msg; 547 struct GNUNET_TESTING_CommandHelperInit *msg;
489 struct TestingSystemCount *tbc; 548 struct TestingSystemCount *tbc;
490 char *m_char; 549 char *m_char;
491 char *n_char; 550 char *n_char;
@@ -493,7 +552,7 @@ start_helper (struct NetJailState *ns,
493 char *local_m_char; 552 char *local_m_char;
494 char *known_char; 553 char *known_char;
495 char *node_id; 554 char *node_id;
496 char *plugin; 555 char *plugin_name;
497 char *read_file; 556 char *read_file;
498 pid_t pid; 557 pid_t pid;
499 unsigned int script_num; 558 unsigned int script_num;
@@ -501,10 +560,13 @@ start_helper (struct NetJailState *ns,
501 struct GNUNET_HashCode hc; 560 struct GNUNET_HashCode hc;
502 struct GNUNET_TESTING_NetjailTopology *topology = ns->topology; 561 struct GNUNET_TESTING_NetjailTopology *topology = ns->topology;
503 struct GNUNET_TESTING_NetjailNode *node; 562 struct GNUNET_TESTING_NetjailNode *node;
563 struct GNUNET_TESTING_NetjailNode *barrier_node;
504 struct GNUNET_TESTING_NetjailNamespace *namespace; 564 struct GNUNET_TESTING_NetjailNamespace *namespace;
505 char *data_dir; 565 char *data_dir;
506 char *script_name; 566 char *script_name;
507 567 struct GNUNET_TESTING_Barrier *barriers;
568 struct GNUNET_TESTING_Barrier *pos;
569 struct GNUNET_TESTING_Barrier *barrier;
508 570
509 if (0 == n) 571 if (0 == n)
510 script_num = m - 1; 572 script_num = m - 1;
@@ -579,11 +641,12 @@ start_helper (struct NetJailState *ns,
579 GNUNET_array_append (ns->helper, ns->n_helper, helper); 641 GNUNET_array_append (ns->helper, ns->n_helper, helper);
580 } 642 }
581 643
582 tbc->count = ns->n_helper; 644 GNUNET_TESTING_add_netjail_helper (ns->is,
583 hkey = GNUNET_new (struct GNUNET_ShortHashCode); 645 helper);
584 646
585 plugin = topology->plugin; 647 plugin_name = topology->plugin;
586 648
649 hkey = GNUNET_new (struct GNUNET_ShortHashCode);
587 if (0 == m) 650 if (0 == m)
588 { 651 {
589 652
@@ -597,7 +660,7 @@ start_helper (struct NetJailState *ns,
597 node = GNUNET_CONTAINER_multishortmap_get (topology->map_globals, 660 node = GNUNET_CONTAINER_multishortmap_get (topology->map_globals,
598 hkey); 661 hkey);
599 if (NULL != node->plugin) 662 if (NULL != node->plugin)
600 plugin = node->plugin; 663 plugin_name = node->plugin;
601 } 664 }
602 665
603 } 666 }
@@ -622,24 +685,47 @@ start_helper (struct NetJailState *ns,
622 node = GNUNET_CONTAINER_multishortmap_get (namespace->nodes, 685 node = GNUNET_CONTAINER_multishortmap_get (namespace->nodes,
623 hkey); 686 hkey);
624 if (NULL != node->plugin) 687 if (NULL != node->plugin)
625 plugin = node->plugin; 688 plugin_name = node->plugin;
626 } 689 }
627 } 690 }
628 691
629 692
630 } 693 }
631 694
632 msg = create_helper_init_msg_ (plugin); 695 plugin = GNUNET_new (struct Plugin);
696 plugin->api = GNUNET_PLUGIN_load (plugin_name,
697 NULL);
698 barriers = plugin->api->get_waiting_for_barriers ();
699
700
701 for (pos = barriers; NULL != pos; pos = pos->next)
702 {
703 barrier = GNUNET_TESTING_get_barrier (ns->is, pos->name);
704 if (NULL == barrier || GNUNET_YES == barrier->shadow)
705 {
706 GNUNET_TESTING_barrier_add (ns->is, pos);
707 barrier = pos;
708 barrier->nodes = GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO);
709 }
710 GNUNET_assert (NULL != node);
711 barrier_node = GNUNET_new (struct GNUNET_TESTING_NetjailNode);
712 barrier_node->node_number = node->node_number;
713 barrier_node->expected_reaches = pos->expected_reaches;
714 barrier->expected_reaches = barrier->expected_reaches + pos->expected_reaches;
715 GNUNET_TESTING_barrier_add_node (barrier->nodes, node);
716 }
717 tbc->plugin = plugin;
718
719 msg = create_helper_init_msg_ (plugin_name);
633 720
634 // GNUNET_array_append (tbc->shandle, tbc->n_shandle,
635 tbc->shandle = GNUNET_HELPER_send ( 721 tbc->shandle = GNUNET_HELPER_send (
636 helper, 722 helper,
637 &msg->header, 723 &msg->header,
638 GNUNET_NO, 724 GNUNET_NO,
639 &clear_msg, 725 &clear_msg,
640 tbc); // ); 726 tbc);
641 727
642 if (NULL == tbc->shandle)// [tbc->count - 1]) 728 if (NULL == tbc->shandle)
643 { 729 {
644 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 730 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
645 "Send handle is NULL!\n"); 731 "Send handle is NULL!\n");
diff --git a/src/testing/testing_api_cmd_netjail_stop_testsystem.c b/src/testing/testing_api_cmd_netjail_stop_testsystem.c
index 4215beef6..2e42056dc 100644
--- a/src/testing/testing_api_cmd_netjail_stop_testsystem.c
+++ b/src/testing/testing_api_cmd_netjail_stop_testsystem.c
@@ -118,7 +118,7 @@ stop_testing_system_run (void *cls,
118 + j 118 + j
119 + shs->known 119 + shs->known
120 - 1], 120 - 1],
121 GNUNET_NO); 121 GNUNET_YES);
122 } 122 }
123 } 123 }
124} 124}
diff --git a/src/testing/testing_api_cmd_send_peer_ready.c b/src/testing/testing_api_cmd_send_peer_ready.c
index 5bbabce51..1a2607047 100644
--- a/src/testing/testing_api_cmd_send_peer_ready.c
+++ b/src/testing/testing_api_cmd_send_peer_ready.c
@@ -46,7 +46,7 @@ struct SendPeerReadyState
46 * The message send back to the master loop. 46 * The message send back to the master loop.
47 * 47 *
48 */ 48 */
49 struct GNUNET_CMDS_PEER_STARTED *reply; 49 struct GNUNET_TESTING_CommandPeerStarted *reply;
50}; 50};
51 51
52 52
@@ -86,11 +86,11 @@ send_peer_ready_run (void *cls,
86 struct GNUNET_TESTING_Interpreter *is) 86 struct GNUNET_TESTING_Interpreter *is)
87{ 87{
88 struct SendPeerReadyState *sprs = cls; 88 struct SendPeerReadyState *sprs = cls;
89 struct GNUNET_CMDS_PEER_STARTED *reply; 89 struct GNUNET_TESTING_CommandPeerStarted *reply;
90 size_t msg_length; 90 size_t msg_length;
91 91
92 msg_length = sizeof(struct GNUNET_CMDS_PEER_STARTED); 92 msg_length = sizeof(struct GNUNET_TESTING_CommandPeerStarted);
93 reply = GNUNET_new (struct GNUNET_CMDS_PEER_STARTED); 93 reply = GNUNET_new (struct GNUNET_TESTING_CommandPeerStarted);
94 reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED); 94 reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED);
95 reply->header.size = htons ((uint16_t) msg_length); 95 reply->header.size = htons ((uint16_t) msg_length);
96 sprs->reply = reply; 96 sprs->reply = reply;
diff --git a/src/testing/testing_api_loop.c b/src/testing/testing_api_loop.c
index 90713e45e..420e1cfcc 100644
--- a/src/testing/testing_api_loop.c
+++ b/src/testing/testing_api_loop.c
@@ -28,6 +28,7 @@
28#include "platform.h" 28#include "platform.h"
29#include "gnunet_util_lib.h" 29#include "gnunet_util_lib.h"
30#include "gnunet_testing_ng_lib.h" 30#include "gnunet_testing_ng_lib.h"
31#include "gnunet_testing_barrier.h"
31#include "testing.h" 32#include "testing.h"
32 33
33/** 34/**
@@ -36,6 +37,21 @@
36 */ 37 */
37struct GNUNET_TESTING_Interpreter 38struct GNUNET_TESTING_Interpreter
38{ 39{
40 /**
41 * Send handle for sending messages to netjail nodes.
42 */
43 struct GNUNET_HELPER_SendHandle *sh;
44
45 /**
46 * Array with handles of helper processes for communication with netjails.
47 */
48 const struct GNUNET_HELPER_Handle **helper;
49
50 /**
51 * Size of the array helper.
52 *
53 */
54 unsigned int n_helper;
39 55
40 /** 56 /**
41 * Function to call with the test result. 57 * Function to call with the test result.
@@ -53,6 +69,11 @@ struct GNUNET_TESTING_Interpreter
53 struct GNUNET_TESTING_Command *commands; 69 struct GNUNET_TESTING_Command *commands;
54 70
55 /** 71 /**
72 * Map with barriers for this loop.
73 */
74 struct GNUNET_CONTAINER_MultiShortmap *barriers;
75
76 /**
56 * Number of GNUNET_TESTING_Command in commands. 77 * Number of GNUNET_TESTING_Command in commands.
57 */ 78 */
58 unsigned int cmds_n; 79 unsigned int cmds_n;
@@ -84,6 +105,24 @@ struct GNUNET_TESTING_Interpreter
84 */ 105 */
85 enum GNUNET_GenericReturnValue result; 106 enum GNUNET_GenericReturnValue result;
86 107
108 /**
109 * Is the interpreter finishing?
110 */
111 unsigned int finishing;
112
113};
114
115struct FreeBarrierNodeCbCls
116{
117 /**
118 * The interpreter.
119 */
120 struct GNUNET_TESTING_Interpreter *is;
121
122 /**
123 * The barrier from which the nodes are freed..
124 */
125 struct GNUNET_TESTING_Barrier *barrier;
87}; 126};
88 127
89 128
@@ -215,6 +254,7 @@ finish_test (void *cls)
215 struct GNUNET_TESTING_Command *cmd; 254 struct GNUNET_TESTING_Command *cmd;
216 const char *label; 255 const char *label;
217 256
257 is->finishing = GNUNET_YES;
218 is->final_task = NULL; 258 is->final_task = NULL;
219 label = is->commands[is->ip].label; 259 label = is->commands[is->ip].label;
220 if (NULL == label) 260 if (NULL == label)
@@ -448,7 +488,7 @@ GNUNET_TESTING_finished (struct GNUNET_TESTING_Command *command)
448} 488}
449 489
450 490
451void 491struct GNUNET_TESTING_Interpreter *
452GNUNET_TESTING_run (struct GNUNET_TESTING_Command *commands, 492GNUNET_TESTING_run (struct GNUNET_TESTING_Command *commands,
453 struct GNUNET_TIME_Relative timeout, 493 struct GNUNET_TIME_Relative timeout,
454 GNUNET_TESTING_ResultCallback rc, 494 GNUNET_TESTING_ResultCallback rc,
@@ -460,6 +500,7 @@ GNUNET_TESTING_run (struct GNUNET_TESTING_Command *commands,
460 is = GNUNET_new (struct GNUNET_TESTING_Interpreter); 500 is = GNUNET_new (struct GNUNET_TESTING_Interpreter);
461 is->rc = rc; 501 is->rc = rc;
462 is->rc_cls = rc_cls; 502 is->rc_cls = rc_cls;
503 is->barriers = GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO);
463 /* get the number of commands */ 504 /* get the number of commands */
464 for (i = 0; NULL != commands[i].label; i++) 505 for (i = 0; NULL != commands[i].label; i++)
465 ; 506 ;
@@ -475,6 +516,8 @@ GNUNET_TESTING_run (struct GNUNET_TESTING_Command *commands,
475 is); 516 is);
476 is->task = GNUNET_SCHEDULER_add_now (&interpreter_run, 517 is->task = GNUNET_SCHEDULER_add_now (&interpreter_run,
477 is); 518 is);
519
520 return is;
478} 521}
479 522
480 523
@@ -538,6 +581,211 @@ loop_run (void *cls)
538 mp); 581 mp);
539} 582}
540 583
584/**
585 * Continuation function from GNUNET_HELPER_send()
586 *
587 * @param cls closure
588 * @param result GNUNET_OK on success,
589 * GNUNET_NO if helper process died
590 * GNUNET_SYSERR during GNUNET_HELPER_stop
591 */
592static void
593clear_msg (void *cls, int result)
594{
595 struct GNUNET_TESTING_Interpreter *is = cls;
596
597 GNUNET_assert (NULL != is->sh);
598 GNUNET_free (is->sh);
599 is->sh = NULL;
600}
601
602/**
603 * Adding a helper handle to the interpreter.
604 *
605 * @param is The interpreter.
606 * @param helper The helper handle.
607 */
608void
609GNUNET_TESTING_add_netjail_helper (struct GNUNET_TESTING_Interpreter *is,
610 const struct GNUNET_HELPER_Handle *helper)
611{
612 GNUNET_array_append (is->helper, is->n_helper, helper);
613}
614
615
616/**
617 * Send Message to netjail nodes that a barrier can be advanced.
618 *
619 * @param is The interpreter.
620 * @param global_node_number The node to inform.
621 * @param header The message to send.
622 */
623void
624GNUNET_TESTING_send_message_to_netjail (struct GNUNET_TESTING_Interpreter *is,
625 unsigned int global_node_number,
626 struct GNUNET_MessageHeader *header)
627{
628 const struct GNUNET_HELPER_Handle *helper;
629
630 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
631 "send message of type %u to locals\n",
632 header->type);
633 helper = is->helper[global_node_number - 1];
634 struct GNUNET_HELPER_SendHandle *sh = GNUNET_HELPER_send (
635 (struct GNUNET_HELPER_Handle *) helper,
636 header,
637 GNUNET_NO,
638 &clear_msg,
639 is);
640}
641
642
643int
644free_barrier_node_cb (void *cls,
645 const struct GNUNET_ShortHashCode *key,
646 void *value)
647{
648 struct FreeBarrierNodeCbCls *free_barrier_node_cb_cls = cls;
649 struct GNUNET_TESTING_NetjailNode *node = value;
650 struct GNUNET_TESTING_Barrier *barrier = free_barrier_node_cb_cls->barrier;
651 struct GNUNET_TESTING_Interpreter *is = free_barrier_node_cb_cls->is;
652
653 if (GNUNET_NO == is->finishing)
654 {
655 GNUNET_TESTING_send_barrier_advance (is,
656 barrier->name,
657 node->node_number);
658 }
659 GNUNET_CONTAINER_multishortmap_remove (barrier->nodes, key, node);
660}
661
662
663/**
664 * Finish all "barrier reached" comands attached to this barrier.
665 *
666 * @param barrier The barrier in question.
667 */
668void
669GNUNET_TESTING_finish_attached_cmds (struct GNUNET_TESTING_Interpreter *is,
670 struct GNUNET_TESTING_Barrier *barrier)
671{
672 struct GNUNET_TESTING_Command *pos;
673 struct FreeBarrierNodeCbCls *free_barrier_node_cb_cls;
674
675 while (NULL != (pos = barrier->cmds_head))
676 {
677 if (GNUNET_NO == pos->ac->finished && GNUNET_NO == pos->asynchronous_finish)
678 {
679 GNUNET_TESTING_async_finish (pos->ac);
680 }
681 else if (GNUNET_NO == pos->ac->finished)
682 {
683 pos->asynchronous_finish = GNUNET_YES;
684 }
685 GNUNET_CONTAINER_DLL_remove (barrier->cmds_head,
686 barrier->cmds_tail,
687 pos);
688 GNUNET_free (pos);
689 }
690 free_barrier_node_cb_cls = GNUNET_new (struct FreeBarrierNodeCbCls);
691 free_barrier_node_cb_cls->barrier = barrier;
692 free_barrier_node_cb_cls->is = is;
693 GNUNET_CONTAINER_multishortmap_iterate (barrier->nodes, free_barrier_node_cb, free_barrier_node_cb_cls);
694 GNUNET_CONTAINER_multishortmap_destroy (barrier->nodes);
695 GNUNET_free (free_barrier_node_cb_cls);
696}
697
698
699int
700free_barriers_cb (void *cls,
701 const struct GNUNET_ShortHashCode *key,
702 void *value)
703{
704 struct GNUNET_TESTING_Interpreter *is = cls;
705 struct GNUNET_TESTING_Barrier *barrier = value;
706 struct GNUNET_TESTING_Command *pos;
707 struct GNUNET_TESTING_NetjailNode *node;
708 struct FreeBarrierNodeCbCls *free_barrier_node_cb_cls;
709
710 free_barrier_node_cb_cls = GNUNET_new (struct FreeBarrierNodeCbCls);
711 free_barrier_node_cb_cls->barrier = barrier;
712 free_barrier_node_cb_cls->is = is;
713 GNUNET_CONTAINER_multishortmap_iterate (barrier->nodes, free_barrier_node_cb, free_barrier_node_cb_cls);
714 GNUNET_CONTAINER_multishortmap_destroy (barrier->nodes);
715
716 while (NULL != (pos = barrier->cmds_head))
717 {
718 GNUNET_CONTAINER_DLL_remove (barrier->cmds_head,
719 barrier->cmds_tail,
720 pos);
721 GNUNET_free (pos);
722 }
723 GNUNET_free (barrier);
724}
725
726
727/**
728 * Deleting all barriers create in the context of this interpreter.
729 *
730 * @param is The interpreter.
731 */
732void
733GNUNET_TESTING_delete_barriers (struct GNUNET_TESTING_Interpreter *is)
734{
735 GNUNET_CONTAINER_multishortmap_iterate (is->barriers,
736 free_barriers_cb,
737 is);
738 GNUNET_CONTAINER_multishortmap_destroy (is->barriers);
739}
740
741/**
742 * Getting a barrier from the interpreter.
743 *
744 * @param is The interpreter.
745 * @param barrier_name The name of the barrier.
746 * @return The barrier.
747 */
748struct GNUNET_TESTING_Barrier *
749GNUNET_TESTING_get_barrier (struct GNUNET_TESTING_Interpreter *is,
750 const char *barrier_name)
751{
752 struct GNUNET_HashCode hc;
753 struct GNUNET_ShortHashCode create_key;
754 struct GNUNET_TESTING_Barrier *barrier;
755 unsigned int kx;
756
757 GNUNET_CRYPTO_hash (barrier_name, strlen(barrier_name), &hc);
758 memcpy (&create_key,
759 &hc,
760 sizeof (create_key));
761 barrier = GNUNET_CONTAINER_multishortmap_get (is->barriers, &create_key);
762 //GNUNET_free (create_key);
763 return barrier;
764}
765
766/**
767 * Add a barrier to the loop.
768 *
769 * @param is The interpreter.
770 * @param barrier The barrier to add.
771 */
772void
773GNUNET_TESTING_barrier_add (struct GNUNET_TESTING_Interpreter *is,
774 struct GNUNET_TESTING_Barrier *barrier)
775{
776 struct GNUNET_HashCode hc;
777 struct GNUNET_ShortHashCode create_key;
778
779 GNUNET_CRYPTO_hash (barrier->name, strlen(barrier->name), &hc);
780 memcpy (&create_key,
781 &hc,
782 sizeof (create_key));
783 GNUNET_CONTAINER_multishortmap_put (is->barriers,
784 &create_key,
785 barrier,
786 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
787}
788
541 789
542int 790int
543GNUNET_TESTING_main (struct GNUNET_TESTING_Command *commands, 791GNUNET_TESTING_main (struct GNUNET_TESTING_Command *commands,
diff --git a/src/testing/testing_cmds.h b/src/testing/testing_cmds.h
index c4246d51e..edc4dfe19 100644
--- a/src/testing/testing_cmds.h
+++ b/src/testing/testing_cmds.h
@@ -32,9 +32,61 @@
32GNUNET_NETWORK_STRUCT_BEGIN 32GNUNET_NETWORK_STRUCT_BEGIN
33 33
34/** 34/**
35 * Handle for a plugin.
36 */
37struct Plugin
38{
39 /**
40 * Name of the shared library.
41 */
42 char *library_name;
43
44 /**
45 * Plugin API.
46 */
47 struct GNUNET_TESTING_PluginFunctions *api;
48
49 /**
50 * IP address of the specific node the helper is running for.
51 *
52 */
53 char *node_ip;
54
55 /**
56 * Name of the test case plugin.
57 *
58 */
59 char *plugin_name;
60
61 /**
62 * The number of namespaces
63 *
64 */
65 char *global_n;
66
67 /**
68 * The number of local nodes per namespace.
69 *
70 */
71 char *local_m;
72
73 /**
74 * The number of the namespace this node is in.
75 *
76 */
77 char *n;
78
79 /**
80 * The number of the node in the namespace.
81 *
82 */
83 char *m;
84};
85
86/**
35 * Initialization message for gnunet-cmds-testbed to start cmd binary. 87 * Initialization message for gnunet-cmds-testbed to start cmd binary.
36 */ 88 */
37struct GNUNET_CMDS_HelperInit 89struct GNUNET_TESTING_CommandHelperInit
38{ 90{
39 /** 91 /**
40 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT 92 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT
@@ -53,7 +105,7 @@ struct GNUNET_CMDS_HelperInit
53/** 105/**
54 * Reply message from cmds helper process 106 * Reply message from cmds helper process
55 */ 107 */
56struct GNUNET_CMDS_HelperReply 108struct GNUNET_TESTING_CommandHelperReply
57{ 109{
58 /** 110 /**
59 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY 111 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY
@@ -61,7 +113,7 @@ struct GNUNET_CMDS_HelperReply
61 struct GNUNET_MessageHeader header; 113 struct GNUNET_MessageHeader header;
62}; 114};
63 115
64struct GNUNET_CMDS_PEER_STARTED 116struct GNUNET_TESTING_CommandPeerStarted
65{ 117{
66 /** 118 /**
67 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED 119 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED
@@ -69,7 +121,7 @@ struct GNUNET_CMDS_PEER_STARTED
69 struct GNUNET_MessageHeader header; 121 struct GNUNET_MessageHeader header;
70}; 122};
71 123
72struct GNUNET_CMDS_ALL_PEERS_STARTED 124struct GNUNET_TESTING_CommandAllPeersStarted
73{ 125{
74 /** 126 /**
75 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED 127 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED
@@ -86,7 +138,7 @@ struct GNUNET_CMDS_LOCAL_FINISHED
86}; 138};
87 139
88 140
89struct GNUNET_CMDS_LOCAL_TEST_PREPARED 141struct GNUNET_TESTING_CommandLocalTestPrepared
90{ 142{
91 /** 143 /**
92 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_TEST_PREPARED 144 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_TEST_PREPARED
@@ -94,7 +146,7 @@ struct GNUNET_CMDS_LOCAL_TEST_PREPARED
94 struct GNUNET_MessageHeader header; 146 struct GNUNET_MessageHeader header;
95}; 147};
96 148
97struct GNUNET_CMDS_ALL_LOCAL_TESTS_PREPARED 149struct GNUNET_TESTING_CommandAllLocalTestsPrepared
98{ 150{
99 /** 151 /**
100 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_LOCAL_TESTS_PREPARED 152 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_LOCAL_TESTS_PREPARED