aboutsummaryrefslogtreecommitdiff
path: root/src/service/arm/testing_arm_cmd_start_peer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/service/arm/testing_arm_cmd_start_peer.c')
-rw-r--r--src/service/arm/testing_arm_cmd_start_peer.c293
1 files changed, 293 insertions, 0 deletions
diff --git a/src/service/arm/testing_arm_cmd_start_peer.c b/src/service/arm/testing_arm_cmd_start_peer.c
new file mode 100644
index 000000000..73d7ca4e7
--- /dev/null
+++ b/src/service/arm/testing_arm_cmd_start_peer.c
@@ -0,0 +1,293 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2021 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_api_cmd_start_peer.c
23 * @brief cmd to start a peer.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_testing_lib.h"
29#include "gnunet_testbed_lib.h"
30#include "gnunet_testing_testbed_lib.h"
31#include "gnunet_testing_arm_lib.h"
32
33
34/**
35 * Handle for a peer controlled via ARM.
36 */
37struct GNUNET_TESTING_StartPeerState
38{
39
40 const char *system_label;
41
42 const char *cfgname;
43
44 /**
45 * Our interpreter.
46 */
47 struct GNUNET_TESTING_Interpreter *is;
48
49 /**
50 * Asynchronous start context.
51 */
52 struct GNUNET_TESTING_AsyncContext ac;
53
54 /**
55 * The TESTBED system associated with this peer
56 */
57 struct GNUNET_TESTBED_System *system;
58
59 /**
60 * The handle to the peer's ARM service
61 */
62 struct GNUNET_ARM_Handle *ah;
63
64 /**
65 * Handle to the ARM process information.
66 */
67 struct GNUNET_OS_Process *arm;
68
69 /**
70 * The config of the peer
71 */
72 struct GNUNET_CONFIGURATION_Handle *cfg;
73
74};
75
76
77/**
78 * Function called whenever we connect to or disconnect from ARM.
79 *
80 * @param cls closure
81 * @param connected #GNUNET_YES if connected, #GNUNET_NO if disconnected,
82 * #GNUNET_SYSERR if there was an error.
83 */
84static void
85conn_status (
86 void *cls,
87 enum GNUNET_GenericReturnValue connected)
88{
89 struct GNUNET_TESTING_StartPeerState *sps = cls;
90
91 if (GNUNET_OK != connected)
92 {
93 GNUNET_break (0);
94 GNUNET_TESTING_async_fail (&sps->ac);
95 return;
96 }
97 GNUNET_TESTING_async_finish (&sps->ac);
98}
99
100
101/**
102 * The run method of this cmd will start all services of a peer to test the transport service.
103 *
104 */
105static void
106start_peer_run (void *cls,
107 struct GNUNET_TESTING_Interpreter *is)
108{
109 struct GNUNET_TESTING_StartPeerState *sps = cls;
110 const struct GNUNET_TESTING_Command *system_cmd;
111
112 sps->is = is;
113 if (GNUNET_NO ==
114 GNUNET_DISK_file_test (sps->cfgname))
115 {
116 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
117 "File not found: `%s'\n",
118 sps->cfgname);
119 GNUNET_TESTING_FAIL (is);
120 }
121 system_cmd
122 = GNUNET_TESTING_interpreter_lookup_command (is,
123 sps->system_label);
124 if (NULL == system_cmd)
125 GNUNET_TESTING_FAIL (is);
126 if (GNUNET_OK !=
127 GNUNET_TESTING_TESTBED_get_trait_test_system (
128 system_cmd,
129 &sps->system))
130 GNUNET_TESTING_FAIL (is);
131 sps->cfg = GNUNET_CONFIGURATION_create ();
132 if (GNUNET_OK !=
133 GNUNET_CONFIGURATION_load (sps->cfg,
134 sps->cfgname))
135 GNUNET_TESTING_FAIL (is);
136 if (GNUNET_SYSERR ==
137 GNUNET_TESTBED_configuration_create (sps->system,
138 sps->cfg,
139 NULL,
140 NULL))
141 GNUNET_TESTING_FAIL (is);
142 {
143 char *config_filename;
144 char *libexec_binary;
145 char *main_binary;
146 char *args;
147 char *prefix;
148
149 GNUNET_assert (
150 GNUNET_OK ==
151 GNUNET_CONFIGURATION_get_value_filename (
152 sps->cfg,
153 "PATHS",
154 "DEFAULTCONFIG",
155 &config_filename));
156 if (GNUNET_OK !=
157 GNUNET_CONFIGURATION_write (sps->cfg,
158 config_filename))
159 {
160 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
161 "Failed to write configuration file `%s': %s\n",
162 config_filename,
163 strerror (errno));
164 GNUNET_free (config_filename);
165 GNUNET_TESTING_FAIL (is);
166 }
167
168 libexec_binary
169 = GNUNET_OS_get_libexec_binary_path ("gnunet-service-arm");
170
171 if (GNUNET_SYSERR ==
172 GNUNET_CONFIGURATION_get_value_string (sps->cfg,
173 "arm",
174 "PREFIX",
175 &prefix))
176 {
177 /* No prefix */
178 main_binary = libexec_binary;
179 args = GNUNET_strdup ("");
180 }
181 else
182 {
183 main_binary = prefix;
184 args = libexec_binary;
185 }
186 sps->arm
187 = GNUNET_OS_start_process_s (GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
188 NULL,
189 main_binary,
190 args,
191 "-c",
192 config_filename,
193 NULL);
194 if (NULL == sps->arm)
195 {
196 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
197 _ ("Failed to start `%s': %s\n"),
198 main_binary,
199 strerror (errno));
200 GNUNET_TESTING_FAIL (is);
201 }
202 GNUNET_free (config_filename);
203 GNUNET_free (main_binary);
204 GNUNET_free (args);
205 }
206
207 sps->ah = GNUNET_ARM_connect (sps->cfg,
208 &conn_status,
209 sps);
210 if (NULL == sps->ah)
211 GNUNET_TESTING_FAIL (is);
212}
213
214
215/**
216 * The cleanup function of this cmd frees resources the cmd allocated.
217 *
218 */
219static void
220start_peer_cleanup (void *cls)
221{
222 struct GNUNET_TESTING_StartPeerState *sps = cls;
223
224 if (NULL != sps->ah)
225 {
226 GNUNET_ARM_disconnect (sps->ah);
227 sps->ah = NULL;
228 }
229 if (NULL != sps->arm)
230 {
231 GNUNET_break (0 ==
232 GNUNET_OS_process_kill (sps->arm,
233 SIGTERM));
234 GNUNET_break (GNUNET_OK ==
235 GNUNET_OS_process_wait (sps->arm));
236 GNUNET_OS_process_destroy (sps->arm);
237 sps->ah = NULL;
238 }
239
240 if (NULL != sps->cfg)
241 {
242 GNUNET_CONFIGURATION_destroy (sps->cfg);
243 sps->cfg = NULL;
244 }
245 GNUNET_free (sps);
246}
247
248
249/**
250 * This function prepares an array with traits.
251 *
252 */
253static enum GNUNET_GenericReturnValue
254start_peer_traits (void *cls,
255 const void **ret,
256 const char *trait,
257 unsigned int index)
258{
259 struct GNUNET_TESTING_StartPeerState *sps = cls;
260 struct GNUNET_TESTING_Trait traits[] = {
261 GNUNET_TESTING_make_trait_process (
262 &sps->arm),
263 // FIXME: expose sps->cfg as trait...
264 GNUNET_TESTING_ARM_make_trait_arm_handle (
265 sps->ah),
266 GNUNET_TESTING_trait_end ()
267 };
268
269 return GNUNET_TESTING_get_trait (traits,
270 ret,
271 trait,
272 index);
273}
274
275
276struct GNUNET_TESTING_Command
277GNUNET_TESTING_ARM_cmd_start_peer (
278 const char *label,
279 const char *system_label,
280 const char *cfgname)
281{
282 struct GNUNET_TESTING_StartPeerState *sps;
283
284 sps = GNUNET_new (struct GNUNET_TESTING_StartPeerState);
285 sps->system_label = GNUNET_strdup (system_label);
286 sps->cfgname = cfgname;
287 return GNUNET_TESTING_command_new_ac (sps,
288 label,
289 &start_peer_run,
290 &start_peer_cleanup,
291 &start_peer_traits,
292 &sps->ac);
293}