diff options
Diffstat (limited to 'src/service/arm/testing_arm_cmd_start_peer.c')
-rw-r--r-- | src/service/arm/testing_arm_cmd_start_peer.c | 293 |
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 | */ | ||
37 | struct 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 | */ | ||
84 | static void | ||
85 | conn_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 | */ | ||
105 | static void | ||
106 | start_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 | */ | ||
219 | static void | ||
220 | start_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 | */ | ||
253 | static enum GNUNET_GenericReturnValue | ||
254 | start_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 | |||
276 | struct GNUNET_TESTING_Command | ||
277 | GNUNET_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 | } | ||