aboutsummaryrefslogtreecommitdiff
path: root/src/lib/testing/testing_api_cmd_barrier_reached.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/testing/testing_api_cmd_barrier_reached.c')
-rw-r--r--src/lib/testing/testing_api_cmd_barrier_reached.c189
1 files changed, 189 insertions, 0 deletions
diff --git a/src/lib/testing/testing_api_cmd_barrier_reached.c b/src/lib/testing/testing_api_cmd_barrier_reached.c
new file mode 100644
index 000000000..35d3cbcd9
--- /dev/null
+++ b/src/lib/testing/testing_api_cmd_barrier_reached.c
@@ -0,0 +1,189 @@
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_lib.h"
28#include "testing_api_loop.h"
29#include "testing_cmds.h"
30
31/**
32 * Generic logging shortcut
33 */
34#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
35
36/**
37 * Struct with information for callbacks.
38 *
39 */
40struct BarrierReachedState
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
59
60/**
61 * Run the command.
62 *
63 * @param cls closure.
64 * @param is the interpreter state.
65 */
66static void
67barrier_reached_run (void *cls,
68 struct GNUNET_TESTING_Interpreter *is)
69{
70 struct BarrierReachedState *brs = cls;
71 struct GNUNET_TESTING_Barrier *barrier;
72
73 barrier = GNUNET_TESTING_get_barrier_ (is,
74 brs->barrier_name);
75 if (NULL == barrier)
76 {
77 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
78 "No barrier `%s'\n",
79 brs->barrier_name);
80 GNUNET_TESTING_async_fail (&brs->ac);
81 return;
82 }
83 if (barrier->satisfied)
84 {
85 GNUNET_TESTING_async_finish (&brs->ac);
86 return;
87 }
88 if (barrier->inherited)
89 {
90 struct GNUNET_TESTING_CommandBarrierReached cbr = {
91 .header.size = htons (sizeof (cbr)),
92 .header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_REACHED)
93 };
94
95 GNUNET_TESTING_barrier_name_hash_ (brs->barrier_name,
96 &cbr.barrier_key);
97 GNUNET_TESTING_loop_notify_parent_ (is,
98 &cbr.header);
99 return;
100 }
101 barrier->reached++;
102 if (barrier->reached == barrier->expected_reaches)
103 {
104 struct GNUNET_TESTING_CommandBarrierSatisfied cbs = {
105 .header.size = htons (sizeof (cbs)),
106 .header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_CROSSABLE)
107 };
108
109 GNUNET_TESTING_barrier_name_hash_ (brs->barrier_name,
110 &cbs.barrier_key);
111 barrier->satisfied = true;
112 GNUNET_TESTING_loop_notify_children_ (is,
113 &cbs.header);
114 }
115 if (barrier->satisfied)
116 {
117 GNUNET_TESTING_async_finish (&brs->ac);
118 for (unsigned int i = 0; i<barrier->cnt_waiting; i++)
119 GNUNET_TESTING_async_finish (barrier->waiting[i]);
120 GNUNET_array_grow (barrier->waiting,
121 barrier->cnt_waiting,
122 0);
123 return;
124 }
125 GNUNET_array_append (barrier->waiting,
126 barrier->cnt_waiting,
127 &brs->ac);
128}
129
130
131/**
132 * Cleanup the state from a "barrier reached" CMD, and possibly
133 * cancel a pending operation thereof.
134 *
135 * @param cls closure.
136 */
137static void
138barrier_reached_cleanup (void *cls)
139{
140 struct BarrierReachedState *brs = cls;
141
142 GNUNET_free (brs);
143}
144
145
146/**
147 * Offer internal data from a "batch" CMD, to other commands.
148 *
149 * @param cls closure.
150 * @param[out] ret result.
151 * @param trait name of the trait.
152 * @param index index number of the object to offer.
153 * @return #GNUNET_OK on success.
154 */
155static enum GNUNET_GenericReturnValue
156barrier_reached_traits (void *cls,
157 const void **ret,
158 const char *trait,
159 unsigned int index)
160{
161 struct GNUNET_TESTING_Trait traits[] = {
162 GNUNET_TESTING_trait_end ()
163 };
164
165 return GNUNET_TESTING_get_trait (traits,
166 ret,
167 trait,
168 index);
169}
170
171
172struct GNUNET_TESTING_Command
173GNUNET_TESTING_cmd_barrier_reached (
174 const char *label,
175 const char *barrier_label)
176{
177 struct BarrierReachedState *brs;
178
179 brs = GNUNET_new (struct BarrierReachedState);
180 brs->label = label;
181 brs->barrier_name = barrier_label;
182 return GNUNET_TESTING_command_new_ac (
183 brs,
184 label,
185 &barrier_reached_run,
186 &barrier_reached_cleanup,
187 &barrier_reached_traits,
188 &brs->ac);
189}