aboutsummaryrefslogtreecommitdiff
path: root/src/testing/testing_api_cmd_barrier.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/testing/testing_api_cmd_barrier.c')
-rw-r--r--src/testing/testing_api_cmd_barrier.c256
1 files changed, 256 insertions, 0 deletions
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}