diff options
author | t3sserakt <t3ss@posteo.de> | 2021-04-15 15:35:28 +0200 |
---|---|---|
committer | t3sserakt <t3ss@posteo.de> | 2021-04-15 15:35:28 +0200 |
commit | 925c210d978cd0e3dfc718d9e4c65ad713a817b9 (patch) | |
tree | b769182d686220816a387336d525f37124dbad72 | |
parent | a785d16b7f49947458782f65f344036a848f4ac7 (diff) | |
download | gnunet-925c210d978cd0e3dfc718d9e4c65ad713a817b9.tar.gz gnunet-925c210d978cd0e3dfc718d9e4c65ad713a817b9.zip |
- added handling of asynchronous task to testing ng. added testbed commands for setting up test invironment (atm wihtout the use of the ne async handling)
-rw-r--r-- | src/include/gnunet_testbed_ng_service.h | 35 | ||||
-rw-r--r-- | src/include/gnunet_testing_ng_lib.h | 104 | ||||
-rw-r--r-- | src/testbed/testbed_api_cmd_controller.c | 1 | ||||
-rw-r--r-- | src/testbed/testbed_api_cmd_peer.c | 40 | ||||
-rw-r--r-- | src/testbed/testbed_api_cmd_peer_store.c | 60 | ||||
-rw-r--r-- | src/testbed/testbed_api_cmd_service.c | 140 | ||||
-rw-r--r-- | src/testbed/testbed_api_cmd_tng_connect.c | 55 | ||||
-rw-r--r-- | src/testbed/testbed_api_cmd_tng_service.c | 276 | ||||
-rw-r--r-- | src/testing/testing.h | 74 | ||||
-rw-r--r-- | src/testing/testing_api_cmd_batch.c | 3 | ||||
-rw-r--r-- | src/testing/testing_api_cmd_hello_world.c | 1 | ||||
-rw-r--r-- | src/testing/testing_api_cmd_hello_world_birth.c | 1 | ||||
-rw-r--r-- | src/testing/testing_api_loop.c | 186 | ||||
-rw-r--r-- | src/transport/transport-testing-ng.h | 71 |
14 files changed, 798 insertions, 249 deletions
diff --git a/src/include/gnunet_testbed_ng_service.h b/src/include/gnunet_testbed_ng_service.h index a6f30889f..370617e68 100644 --- a/src/include/gnunet_testbed_ng_service.h +++ b/src/include/gnunet_testbed_ng_service.h | |||
@@ -38,33 +38,7 @@ | |||
38 | #include "gnunet_util_lib.h" | 38 | #include "gnunet_util_lib.h" |
39 | #include "gnunet_testing_ng_lib.h" | 39 | #include "gnunet_testing_ng_lib.h" |
40 | 40 | ||
41 | struct ServiceState | 41 | struct TngState; |
42 | { | ||
43 | /** | ||
44 | * Handle to operation | ||
45 | */ | ||
46 | struct GNUNET_TESTBED_Operation *operation; | ||
47 | |||
48 | /** | ||
49 | * Flag indicating if service is ready. | ||
50 | */ | ||
51 | int service_ready; | ||
52 | |||
53 | /** | ||
54 | * Abort task identifier | ||
55 | */ | ||
56 | struct GNUNET_SCHEDULER_Task *abort_task; | ||
57 | |||
58 | /** | ||
59 | * Label of peer command. | ||
60 | */ | ||
61 | const char *peer_label; | ||
62 | |||
63 | /** | ||
64 | * Name of service to start. | ||
65 | */ | ||
66 | const char *servicename; | ||
67 | }; | ||
68 | 42 | ||
69 | struct PeerCmdState | 43 | struct PeerCmdState |
70 | { | 44 | { |
@@ -111,11 +85,6 @@ struct PeerCmdState | |||
111 | struct GNUNET_SCHEDULER_Task *abort_task; | 85 | struct GNUNET_SCHEDULER_Task *abort_task; |
112 | 86 | ||
113 | /** | 87 | /** |
114 | * Handle for host registration | ||
115 | */ | ||
116 | struct GNUNET_TESTBED_HostRegistrationHandle *reg_handle; | ||
117 | |||
118 | /** | ||
119 | * Flag indicating if peer is ready. | 88 | * Flag indicating if peer is ready. |
120 | */ | 89 | */ |
121 | int peer_ready; | 90 | int peer_ready; |
@@ -242,6 +211,6 @@ void | |||
242 | GNUNET_TESTBED_shutdown_peer (struct PeerCmdState *ps); | 211 | GNUNET_TESTBED_shutdown_peer (struct PeerCmdState *ps); |
243 | 212 | ||
244 | void | 213 | void |
245 | GNUNET_TESTBED_shutdown_service (struct ServiceState *ss); | 214 | GNUNET_TESTBED_shutdown_service (struct TngState *ss); |
246 | 215 | ||
247 | #endif | 216 | #endif |
diff --git a/src/include/gnunet_testing_ng_lib.h b/src/include/gnunet_testing_ng_lib.h index 0bc516614..001d92aad 100644 --- a/src/include/gnunet_testing_ng_lib.h +++ b/src/include/gnunet_testing_ng_lib.h | |||
@@ -51,46 +51,7 @@ | |||
51 | * Global state of the interpreter, used by a command | 51 | * Global state of the interpreter, used by a command |
52 | * to access information about other commands. | 52 | * to access information about other commands. |
53 | */ | 53 | */ |
54 | // SUGGESTION: consider making this struct opaque (only known inside of libgnunettesting, | 54 | struct GNUNET_TESTING_Interpreter; |
55 | // say main loop and a few select commands, like next/fail/batch); + helper | ||
56 | // function to access 'cfg'? | ||
57 | struct GNUNET_TESTING_Interpreter | ||
58 | { | ||
59 | |||
60 | /** | ||
61 | * Commands the interpreter will run. | ||
62 | */ | ||
63 | struct GNUNET_TESTING_Command *commands; | ||
64 | |||
65 | /** | ||
66 | * Interpreter task (if one is scheduled). | ||
67 | */ | ||
68 | struct GNUNET_SCHEDULER_Task *task; | ||
69 | |||
70 | /** | ||
71 | * Our configuration. | ||
72 | */ | ||
73 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
74 | |||
75 | /** | ||
76 | * Task run on timeout. | ||
77 | */ | ||
78 | struct GNUNET_SCHEDULER_Task *timeout_task; | ||
79 | |||
80 | /** | ||
81 | * Instruction pointer. Tells #interpreter_run() which instruction to run | ||
82 | * next. Need (signed) int because it gets -1 when rewinding the | ||
83 | * interpreter to the first CMD. | ||
84 | */ | ||
85 | int ip; | ||
86 | |||
87 | /** | ||
88 | * Result of the testcases, #GNUNET_OK on success | ||
89 | */ | ||
90 | int result; | ||
91 | |||
92 | }; | ||
93 | |||
94 | 55 | ||
95 | /** | 56 | /** |
96 | * A command to be run by the interpreter. | 57 | * A command to be run by the interpreter. |
@@ -131,21 +92,26 @@ struct GNUNET_TESTING_Command | |||
131 | 92 | ||
132 | /** | 93 | /** |
133 | * Wait for any asynchronous execution of @e run to conclude, | 94 | * Wait for any asynchronous execution of @e run to conclude, |
134 | * then call @a cont. Finish may only be called once per command. | 95 | * then call finish_cont. Finish may only be called once per command. |
135 | * | 96 | * |
136 | * This member may be NULL if this command is a synchronous command, | 97 | * This member may be NULL if this command is a synchronous command, |
137 | * and also should be set to NULL once the command has finished. | 98 | * and also should be set to NULL once the command has finished. |
138 | * | 99 | * |
100 | * @param cls closure | ||
139 | * @param cont function to call upon completion, can be NULL | 101 | * @param cont function to call upon completion, can be NULL |
140 | * @param cont_cls closure for @a cont | 102 | * @param cont_cls closure for @a cont |
141 | */ | 103 | */ |
142 | // SUGGESTION (NEW!) | 104 | bool |
143 | void | ||
144 | (*finish)(void *cls, | 105 | (*finish)(void *cls, |
145 | struct GNUNET_SCHEDULER_Task cont, | 106 | GNUNET_SCHEDULER_TaskCallback cont, |
146 | void *cont_cls); | 107 | void *cont_cls); |
147 | 108 | ||
148 | /** | 109 | /** |
110 | * Task for running the finish function. | ||
111 | */ | ||
112 | struct GNUNET_SCHEDULER_Task *finish_task; | ||
113 | |||
114 | /** | ||
149 | * Clean up after the command. Run during forced termination | 115 | * Clean up after the command. Run during forced termination |
150 | * (CTRL-C) or test failure or test success. | 116 | * (CTRL-C) or test failure or test success. |
151 | * | 117 | * |
@@ -206,7 +172,6 @@ struct GNUNET_TESTING_Command | |||
206 | * time, the interpreter will fail. Should be set generously to ensure | 172 | * time, the interpreter will fail. Should be set generously to ensure |
207 | * tests do not fail on slow systems. | 173 | * tests do not fail on slow systems. |
208 | */ | 174 | */ |
209 | // SUGGESTION (NEW): | ||
210 | struct GNUNET_TIME_Relative default_timeout; | 175 | struct GNUNET_TIME_Relative default_timeout; |
211 | 176 | ||
212 | /** | 177 | /** |
@@ -215,13 +180,39 @@ struct GNUNET_TESTING_Command | |||
215 | * #TALER_TESTING_cmd_finish() must be used | 180 | * #TALER_TESTING_cmd_finish() must be used |
216 | * to ensure that a command actually completed. | 181 | * to ensure that a command actually completed. |
217 | */ | 182 | */ |
218 | // SUGGESTION (NEW): | ||
219 | bool asynchronous_finish; | 183 | bool asynchronous_finish; |
220 | 184 | ||
221 | }; | 185 | }; |
222 | 186 | ||
223 | 187 | ||
224 | /** | 188 | /** |
189 | * Struct to use for command-specific context information closure of a command waiting | ||
190 | * for another command. | ||
191 | */ | ||
192 | struct SyncState | ||
193 | { | ||
194 | /** | ||
195 | * Closure for all commands with command-specific context information. | ||
196 | */ | ||
197 | void *cls; | ||
198 | |||
199 | /** | ||
200 | * The asynchronous command the synchronous command of this closure waits for. | ||
201 | */ | ||
202 | const struct GNUNET_TESTING_Command *async_cmd; | ||
203 | |||
204 | /** | ||
205 | * Task for running the finish method of the asynchronous task the command is waiting for. | ||
206 | */ | ||
207 | struct GNUNET_SCHEDULER_Task *finish_task; | ||
208 | |||
209 | /** | ||
210 | * When did the execution of this commands finish function start? | ||
211 | */ | ||
212 | struct GNUNET_TIME_Absolute start_finish_time; | ||
213 | }; | ||
214 | |||
215 | /** | ||
225 | * Lookup command by label. | 216 | * Lookup command by label. |
226 | * | 217 | * |
227 | * @param label label of the command to lookup. | 218 | * @param label label of the command to lookup. |
@@ -244,15 +235,6 @@ GNUNET_TESTING_interpreter_get_current_label ( | |||
244 | 235 | ||
245 | 236 | ||
246 | /** | 237 | /** |
247 | * Current command is done, run the next one. | ||
248 | * | ||
249 | * @param is interpreter state. | ||
250 | */ | ||
251 | void | ||
252 | GNUNET_TESTING_interpreter_next (struct GNUNET_TESTING_Interpreter *is); | ||
253 | |||
254 | |||
255 | /** | ||
256 | * Current command failed, clean up and fail the test case. | 238 | * Current command failed, clean up and fail the test case. |
257 | * | 239 | * |
258 | * @param is interpreter state. | 240 | * @param is interpreter state. |
@@ -271,14 +253,13 @@ GNUNET_TESTING_cmd_end (void); | |||
271 | 253 | ||
272 | 254 | ||
273 | /** | 255 | /** |
274 | * Turn synchronous command into asynchronous command. | 256 | * Turn asynchronous command into non blocking command by setting asynchronous_finish to true. |
275 | * | 257 | * |
276 | * @param cmd command to make synchronous. | 258 | * @param cmd command to make synchronous. |
277 | * @return a finish-command. | 259 | * @return a finish-command. |
278 | */ | 260 | */ |
279 | // SUGGESTION (NEW!) | ||
280 | const struct GNUNET_TESTING_Command | 261 | const struct GNUNET_TESTING_Command |
281 | TALER_TESTING_cmd_make_asynchronous (const struct GNUNET_TESTING_Command cmd); | 262 | GNUNET_TESTING_cmd_make_unblocking (const struct GNUNET_TESTING_Command cmd); |
282 | 263 | ||
283 | 264 | ||
284 | /** | 265 | /** |
@@ -292,11 +273,10 @@ TALER_TESTING_cmd_make_asynchronous (const struct GNUNET_TESTING_Command cmd); | |||
292 | * @param timeout how long to wait at most for @a cmd_ref to finish | 273 | * @param timeout how long to wait at most for @a cmd_ref to finish |
293 | * @return a finish-command. | 274 | * @return a finish-command. |
294 | */ | 275 | */ |
295 | // SUGGESTION (NEW!) | ||
296 | const struct GNUNET_TESTING_Command | 276 | const struct GNUNET_TESTING_Command |
297 | TALER_TESTING_cmd_finish (const char *finish_label, | 277 | GNUNET_TESTING_cmd_finish (const char *finish_label, |
298 | const char *cmd_ref, | 278 | const char *cmd_ref, |
299 | struct GNUNET_TIME_Relative timeout); | 279 | struct GNUNET_TIME_Relative timeout); |
300 | 280 | ||
301 | 281 | ||
302 | /** | 282 | /** |
diff --git a/src/testbed/testbed_api_cmd_controller.c b/src/testbed/testbed_api_cmd_controller.c index d65f41760..da23df1ef 100644 --- a/src/testbed/testbed_api_cmd_controller.c +++ b/src/testbed/testbed_api_cmd_controller.c | |||
@@ -121,7 +121,6 @@ registration_comp (void *cls, | |||
121 | { | 121 | { |
122 | cs->reg_handle = NULL; | 122 | cs->reg_handle = NULL; |
123 | cs->host_ready = GNUNET_YES; | 123 | cs->host_ready = GNUNET_YES; |
124 | GNUNET_TESTING_interpreter_next (cs->is); | ||
125 | } | 124 | } |
126 | } | 125 | } |
127 | 126 | ||
diff --git a/src/testbed/testbed_api_cmd_peer.c b/src/testbed/testbed_api_cmd_peer.c index 4a727bc94..2e253e408 100644 --- a/src/testbed/testbed_api_cmd_peer.c +++ b/src/testbed/testbed_api_cmd_peer.c | |||
@@ -20,8 +20,8 @@ | |||
20 | 20 | ||
21 | 21 | ||
22 | /** | 22 | /** |
23 | * @file testbed/testbed_api_cmd_controller.c | 23 | * @file testbed/testbed_api_cmd_peer.c |
24 | * @brief Command to create a controller. | 24 | * @brief Command to create a peer. |
25 | * @author t3sserakt | 25 | * @author t3sserakt |
26 | */ | 26 | */ |
27 | #include "platform.h" | 27 | #include "platform.h" |
@@ -54,10 +54,43 @@ peer_traits (void *cls, | |||
54 | const char *trait, | 54 | const char *trait, |
55 | unsigned int index) | 55 | unsigned int index) |
56 | { | 56 | { |
57 | (void) cls; | 57 | struct PeerCmdState *ps = cls; |
58 | |||
59 | struct GNUNET_TESTING_Trait traits[] = { | ||
60 | { | ||
61 | .index = 0, | ||
62 | .trait_name = "peer", | ||
63 | .ptr = (const void *) ps->peer, | ||
64 | }, | ||
65 | GNUNET_TESTING_trait_end () | ||
66 | }; | ||
67 | |||
68 | return GNUNET_TESTING_get_trait (traits, | ||
69 | ret, | ||
70 | trait, | ||
71 | index); | ||
72 | |||
58 | return GNUNET_OK; | 73 | return GNUNET_OK; |
59 | } | 74 | } |
60 | 75 | ||
76 | /** | ||
77 | * Offer data from trait | ||
78 | * | ||
79 | * @param cmd command to extract the controller from. | ||
80 | * @param peer pointer GNUNET_TESTBED_PEER | ||
81 | * @return #GNUNET_OK on success. | ||
82 | */ | ||
83 | int | ||
84 | GNUNET_TESTBED_get_trait_peer (const struct GNUNET_TESTING_Command *cmd, | ||
85 | struct GNUNET_TESTBED_Peer ** | ||
86 | peer) | ||
87 | { | ||
88 | return cmd->traits (cmd->cls, | ||
89 | (const void **) peer, | ||
90 | "peer", | ||
91 | (unsigned int) 0); | ||
92 | } | ||
93 | |||
61 | 94 | ||
62 | /** | 95 | /** |
63 | * | 96 | * |
@@ -110,7 +143,6 @@ peer_started_cb (void *cls, | |||
110 | if (NULL == emsg) | 143 | if (NULL == emsg) |
111 | { | 144 | { |
112 | ps->peer_ready = GNUNET_YES; | 145 | ps->peer_ready = GNUNET_YES; |
113 | GNUNET_TESTING_interpreter_next (ps->is); | ||
114 | } | 146 | } |
115 | else | 147 | else |
116 | { | 148 | { |
diff --git a/src/testbed/testbed_api_cmd_peer_store.c b/src/testbed/testbed_api_cmd_peer_store.c new file mode 100644 index 000000000..fc96f589c --- /dev/null +++ b/src/testbed/testbed_api_cmd_peer_store.c | |||
@@ -0,0 +1,60 @@ | |||
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 testbed/testbed_api_cmd_peer_store.c | ||
23 | * @brief Command to start the peer store service of a peer. | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | |||
27 | |||
28 | static void | ||
29 | service_run (void *cls, | ||
30 | const struct GNUNET_TESTING_Command *cmd, | ||
31 | struct GNUNET_TESTING_Interpreter *is) | ||
32 | { | ||
33 | struct PeerStoreState *pss = cls; | ||
34 | |||
35 | pss->psh = GNUNET_PEERSTORE_connect (pss->cfg); | ||
36 | GNUNET_TESTING_interpreter_next (ps->is); | ||
37 | } | ||
38 | |||
39 | |||
40 | struct GNUNET_TESTING_Command | ||
41 | GNUNET_TESTBED_cmd_peer_store (const char *label, | ||
42 | struct GNUNET_CONFIGURATION_Handle *cfg) | ||
43 | { | ||
44 | |||
45 | struct PeerStoreState *pss; | ||
46 | |||
47 | pss = GNUNET_new (struct PeerStoreState); | ||
48 | pss->cfg = cfg; | ||
49 | |||
50 | struct GNUNET_TESTING_Command cmd = { | ||
51 | .cls = pss, | ||
52 | .label = label, | ||
53 | .run = &peer_store_run, | ||
54 | .cleanup = &peer_store_cleanup, | ||
55 | .traits = &peer_store_traits | ||
56 | }; | ||
57 | |||
58 | return cmd; | ||
59 | |||
60 | } | ||
diff --git a/src/testbed/testbed_api_cmd_service.c b/src/testbed/testbed_api_cmd_service.c deleted file mode 100644 index 58b3309de..000000000 --- a/src/testbed/testbed_api_cmd_service.c +++ /dev/null | |||
@@ -1,140 +0,0 @@ | |||
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 testbed/testbed_api_cmd_controller.c | ||
23 | * @brief Command to create a controller. | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_testing_ng_lib.h" | ||
29 | #include "gnunet-service-testbed.h" | ||
30 | #include "testbed_api_hosts.h" | ||
31 | #include "gnunet_testbed_ng_service.h" | ||
32 | |||
33 | /** | ||
34 | * Generic logging shortcut | ||
35 | */ | ||
36 | #define LOG(kind, ...) \ | ||
37 | GNUNET_log (kind, __VA_ARGS__) | ||
38 | |||
39 | |||
40 | /** | ||
41 | * abort task to run on test timed out | ||
42 | * | ||
43 | * @param cls NULL | ||
44 | * @param tc the task context | ||
45 | */ | ||
46 | static void | ||
47 | do_abort (void *cls) | ||
48 | { | ||
49 | struct ServiceState *ss = cls; | ||
50 | |||
51 | if (GNUNET_NO == ss->service_ready) | ||
52 | { | ||
53 | LOG (GNUNET_ERROR_TYPE_WARNING, "Test timedout -- Aborting\n"); | ||
54 | ss->abort_task = NULL; | ||
55 | GNUNET_TESTBED_shutdown_service (ss); | ||
56 | } | ||
57 | } | ||
58 | |||
59 | /** | ||
60 | * | ||
61 | * | ||
62 | * @param cls closure | ||
63 | * @param cmd current CMD being cleaned up. | ||
64 | */ | ||
65 | static void | ||
66 | service_cleanup (void *cls, | ||
67 | const struct GNUNET_TESTING_Command *cmd) | ||
68 | { | ||
69 | (void) cls; | ||
70 | } | ||
71 | |||
72 | /** | ||
73 | * | ||
74 | * | ||
75 | * @param cls closure. | ||
76 | * @param[out] ret result | ||
77 | * @param trait name of the trait. | ||
78 | * @param index index number of the object to offer. | ||
79 | * @return #GNUNET_OK on success. | ||
80 | */ | ||
81 | static int | ||
82 | service_traits (void *cls, | ||
83 | const void **ret, | ||
84 | const char *trait, | ||
85 | unsigned int index) | ||
86 | { | ||
87 | (void) cls; | ||
88 | return GNUNET_OK; | ||
89 | } | ||
90 | |||
91 | static void | ||
92 | service_run (void *cls, | ||
93 | const struct GNUNET_TESTING_Command *cmd, | ||
94 | struct GNUNET_TESTING_Interpreter *is) | ||
95 | { | ||
96 | struct ServiceState *ss = cls; | ||
97 | |||
98 | // TODO this is unfinished code! | ||
99 | ss->operation = | ||
100 | GNUNET_TESTBED_service_connect (NULL, NULL, NULL, | ||
101 | NULL, NULL, | ||
102 | NULL, | ||
103 | NULL, NULL); | ||
104 | |||
105 | } | ||
106 | |||
107 | /** | ||
108 | * Shutdown nicely | ||
109 | * | ||
110 | * @param cs service state. | ||
111 | */ | ||
112 | void | ||
113 | GNUNET_TESTBED_shutdown_service (struct ServiceState *cs) | ||
114 | { | ||
115 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
116 | "Shutting down...\n"); | ||
117 | } | ||
118 | |||
119 | |||
120 | struct GNUNET_TESTING_Command | ||
121 | GNUNET_TESTBED_cmd_service (const char *label, | ||
122 | const char *peer_label, | ||
123 | const char *servicename) | ||
124 | { | ||
125 | struct ServiceState *ss; | ||
126 | |||
127 | ss = GNUNET_new (struct ServiceState); | ||
128 | ss->servicename = servicename; | ||
129 | ss->peer_label = peer_label; | ||
130 | |||
131 | struct GNUNET_TESTING_Command cmd = { | ||
132 | .cls = ss, | ||
133 | .label = label, | ||
134 | .run = &service_run, | ||
135 | .cleanup = &service_cleanup, | ||
136 | .traits = &service_traits | ||
137 | }; | ||
138 | |||
139 | return cmd; | ||
140 | } | ||
diff --git a/src/testbed/testbed_api_cmd_tng_connect.c b/src/testbed/testbed_api_cmd_tng_connect.c new file mode 100644 index 000000000..e52cd3c76 --- /dev/null +++ b/src/testbed/testbed_api_cmd_tng_connect.c | |||
@@ -0,0 +1,55 @@ | |||
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 | /** | ||
23 | * @file testbed/testbed_api_cmd_peer.c | ||
24 | * @brief Command to create a peer. | ||
25 | * @author t3sserakt | ||
26 | */ | ||
27 | |||
28 | |||
29 | static void | ||
30 | tng_connect_run (void *cls, | ||
31 | const struct GNUNET_TESTING_Command *cmd, | ||
32 | struct GNUNET_TESTING_Interpreter *is) | ||
33 | { | ||
34 | struct TngConnectState *tcs = cls; | ||
35 | |||
36 | tcs->ah = GNUNET_TRANSPORT_application_init (tcs->cfg); | ||
37 | } | ||
38 | |||
39 | struct GNUNET_TESTING_Command | ||
40 | GNUNET_TESTBED_cmd_tng_connect (const char *label) | ||
41 | { | ||
42 | struct TngConnectState *tcs; | ||
43 | |||
44 | ts = GNUNET_new (struct TngConnectState); | ||
45 | |||
46 | struct GNUNET_TESTING_Command cmd = { | ||
47 | .cls = tcs, | ||
48 | .label = label, | ||
49 | .run = &tng_connect_run, | ||
50 | .cleanup = &tmg_connect_cleanup, | ||
51 | .traits = &tng_connect_traits | ||
52 | }; | ||
53 | |||
54 | return cmd; | ||
55 | } | ||
diff --git a/src/testbed/testbed_api_cmd_tng_service.c b/src/testbed/testbed_api_cmd_tng_service.c new file mode 100644 index 000000000..f9ef44bad --- /dev/null +++ b/src/testbed/testbed_api_cmd_tng_service.c | |||
@@ -0,0 +1,276 @@ | |||
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 testbed/testbed_api_cmd_tng.c | ||
23 | * @brief Command to start the transport service of a peer. | ||
24 | * @author t3sserakt | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_testing_ng_lib.h" | ||
29 | #include "gnunet-service-testbed.h" | ||
30 | #include "testbed_api_hosts.h" | ||
31 | #include "gnunet_testbed_ng_service.h" | ||
32 | |||
33 | /** | ||
34 | * Generic logging shortcut | ||
35 | */ | ||
36 | #define LOG(kind, ...) \ | ||
37 | GNUNET_log (kind, __VA_ARGS__) | ||
38 | |||
39 | |||
40 | /** | ||
41 | * abort task to run on test timed out | ||
42 | * | ||
43 | * @param cls NULL | ||
44 | * @param tc the task context | ||
45 | */ | ||
46 | static void | ||
47 | do_abort (void *cls) | ||
48 | { | ||
49 | struct TngState *ts = cls; | ||
50 | |||
51 | if (GNUNET_NO == ts->service_ready) | ||
52 | { | ||
53 | LOG (GNUNET_ERROR_TYPE_WARNING, "Test timedout -- Aborting\n"); | ||
54 | ts->abort_task = NULL; | ||
55 | GNUNET_TESTBED_shutdown_service (ts); | ||
56 | } | ||
57 | } | ||
58 | |||
59 | /** | ||
60 | * | ||
61 | * | ||
62 | * @param cls closure | ||
63 | * @param cmd current CMD being cleaned up. | ||
64 | */ | ||
65 | static void | ||
66 | tng_service_cleanup (void *cls, | ||
67 | const struct GNUNET_TESTING_Command *cmd) | ||
68 | { | ||
69 | (void) cls; | ||
70 | } | ||
71 | |||
72 | /** | ||
73 | * | ||
74 | * | ||
75 | * @param cls closure. | ||
76 | * @param[out] ret result | ||
77 | * @param trait name of the trait. | ||
78 | * @param index index number of the object to offer. | ||
79 | * @return #GNUNET_OK on success. | ||
80 | */ | ||
81 | static int | ||
82 | tng_service_traits (void *cls, | ||
83 | const void **ret, | ||
84 | const char *trait, | ||
85 | unsigned int index) | ||
86 | { | ||
87 | (void) cls; | ||
88 | return GNUNET_OK; | ||
89 | } | ||
90 | |||
91 | |||
92 | static void * | ||
93 | notify_connect (void *cls, | ||
94 | const struct GNUNET_PeerIdentity *peer, | ||
95 | struct GNUNET_MQ_Handle *mq) | ||
96 | { | ||
97 | struct TngState *ts = cls; | ||
98 | |||
99 | if (NULL != emsg) | ||
100 | { | ||
101 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
102 | "There was an error starting the transport subsystem: %s\n", | ||
103 | emsg); | ||
104 | } | ||
105 | GNUNET_TESTING_interpreter_next (ps->is); | ||
106 | return ts->nc (ts->cb_cls); | ||
107 | |||
108 | } | ||
109 | |||
110 | |||
111 | static void | ||
112 | notify_disconnect (void *cls, | ||
113 | const struct GNUNET_PeerIdentity *peer, | ||
114 | void *handler_cls) | ||
115 | { | ||
116 | } | ||
117 | |||
118 | |||
119 | |||
120 | |||
121 | /** | ||
122 | * Adapter function called to establish a connection to | ||
123 | * a service. | ||
124 | * | ||
125 | * @param cls closure | ||
126 | * @param cfg configuration of the peer to connect to; will be available until | ||
127 | * GNUNET_TESTBED_operation_done() is called on the operation returned | ||
128 | * from GNUNET_TESTBED_service_connect() | ||
129 | * @return service handle to return in 'op_result', NULL on error | ||
130 | */ | ||
131 | static void * | ||
132 | connect_adapter (void *cls, | ||
133 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
134 | { | ||
135 | struct TngState *ts = cls; | ||
136 | |||
137 | service_handle = GNUNET_TRANSPORT_core_connect (cfg, | ||
138 | ts->peer_identity, | ||
139 | ts->handlers, | ||
140 | ts, | ||
141 | ¬ify_connect, | ||
142 | ¬ify_disconnect); | ||
143 | return service_handle; | ||
144 | } | ||
145 | |||
146 | |||
147 | /** | ||
148 | * Adapter function called to destroy a connection to | ||
149 | * a service. | ||
150 | * | ||
151 | * @param cls closure | ||
152 | * @param op_result service handle returned from the connect adapter | ||
153 | */ | ||
154 | static void | ||
155 | disconnect_adapter (void *cls, | ||
156 | void *op_result) | ||
157 | { | ||
158 | } | ||
159 | |||
160 | /** | ||
161 | * Callback to be called when a service connect operation is completed | ||
162 | * | ||
163 | * @param cls the callback closure from functions generating an operation | ||
164 | * @param op the operation that has been finished | ||
165 | * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter() | ||
166 | * @param emsg error message in case the operation has failed; will be NULL if | ||
167 | * operation has executed successfully. | ||
168 | */ | ||
169 | static void | ||
170 | service_connect_comp_cb (void *cls, | ||
171 | struct GNUNET_TESTBED_Operation *op, | ||
172 | void *ca_result, | ||
173 | const char *emsg) | ||
174 | { | ||
175 | struct TngState *ts = cls; | ||
176 | |||
177 | if (NULL != emsg) | ||
178 | { | ||
179 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
180 | "An error occured connecting to service %s\n", | ||
181 | emsg); | ||
182 | GNUNET_TESTBED_operation_done (ts->operation); | ||
183 | } | ||
184 | } | ||
185 | |||
186 | |||
187 | /** | ||
188 | * Callback to be called when the requested peer information is available | ||
189 | * | ||
190 | * @param cls the closure from GNUNET_TESTBED_peer_getinformation() | ||
191 | * @param op the operation this callback corresponds to | ||
192 | * @param pinfo the result; will be NULL if the operation has failed | ||
193 | * @param emsg error message if the operation has failed; | ||
194 | * NULL if the operation is successfull | ||
195 | */ | ||
196 | static void | ||
197 | pi_cb (void *cls, | ||
198 | struct GNUNET_TESTBED_Operation *op, | ||
199 | const struct GNUNET_TESTBED_PeerInformation *pinfo, | ||
200 | const char *emsg) | ||
201 | { | ||
202 | struct TngState *ts = cls; | ||
203 | |||
204 | ts->peer_identity = pinfo->id; | ||
205 | ts->operation = | ||
206 | GNUNET_TESTBED_service_connect (NULL, peer, NULL, | ||
207 | &service_connect_comp_cb, ts, | ||
208 | &connect_adapter, | ||
209 | &disconnect_adapter, | ||
210 | ts); | ||
211 | } | ||
212 | |||
213 | |||
214 | static void | ||
215 | tng_service_run (void *cls, | ||
216 | const struct GNUNET_TESTING_Command *cmd, | ||
217 | struct GNUNET_TESTING_Interpreter *is) | ||
218 | { | ||
219 | struct TngState *ts = cls; | ||
220 | struct GNUNET_TESTBED_Peer *peer; | ||
221 | const struct GNUNET_TESTING_Command *peer_cmd; | ||
222 | |||
223 | ts->is = is; | ||
224 | peer_cmd = GNUNET_TESTING_interpreter_lookup_command ( | ||
225 | ts->peer_label); | ||
226 | GNUNET_TESTBED_get_trait_peer (peer_cmd, | ||
227 | &peer); | ||
228 | |||
229 | ts->operation = GNUNET_TESTBED_peer_get_information (peer, | ||
230 | GNUNET_TESTBED_PIT_IDENTITY, | ||
231 | &pi_cb, | ||
232 | ts); | ||
233 | } | ||
234 | |||
235 | /** | ||
236 | * Shutdown nicely | ||
237 | * | ||
238 | * @param cs service state. | ||
239 | */ | ||
240 | void | ||
241 | GNUNET_TESTBED_shutdown_service (struct TngState *cs) | ||
242 | { | ||
243 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
244 | "Shutting down...\n"); | ||
245 | } | ||
246 | |||
247 | |||
248 | struct GNUNET_TESTING_Command | ||
249 | GNUNET_TESTBED_cmd_tng_service (const char *label, | ||
250 | const char *peer_label, | ||
251 | const struct GNUNET_MQ_MessageHandler *handlers, | ||
252 | GNUNET_TRANSPORT_NotifyConnect nc, | ||
253 | void *cb_cls) | ||
254 | |||
255 | { | ||
256 | struct TngState *ts; | ||
257 | |||
258 | ts = GNUNET_new (struct TngState); | ||
259 | ts->servicename = servicename; | ||
260 | ts->peer_label = peer_label; | ||
261 | ts->handlers = handlers; | ||
262 | ts->nc = nc; | ||
263 | ts->nd = nd; | ||
264 | ts->cb_cls; | ||
265 | |||
266 | |||
267 | struct GNUNET_TESTING_Command cmd = { | ||
268 | .cls = ts, | ||
269 | .label = label, | ||
270 | .run = &tng_service_run, | ||
271 | .cleanup = &tmg_service_cleanup, | ||
272 | .traits = &tng_service_traits | ||
273 | }; | ||
274 | |||
275 | return cmd; | ||
276 | } | ||
diff --git a/src/testing/testing.h b/src/testing/testing.h new file mode 100644 index 000000000..b12466530 --- /dev/null +++ b/src/testing/testing.h | |||
@@ -0,0 +1,74 @@ | |||
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 | * @author t3sserakt | ||
23 | */ | ||
24 | |||
25 | #include "gnunet_util_lib.h" | ||
26 | |||
27 | /** | ||
28 | * Global state of the interpreter, used by a command | ||
29 | * to access information about other commands. | ||
30 | */ | ||
31 | // SUGGESTION: consider making this struct opaque (only known inside of libgnunettesting, | ||
32 | // say main loop and a few select commands, like next/fail/batch); + helper | ||
33 | // function to access 'cfg'? | ||
34 | struct GNUNET_TESTING_Interpreter | ||
35 | { | ||
36 | |||
37 | /** | ||
38 | * Commands the interpreter will run. | ||
39 | */ | ||
40 | struct GNUNET_TESTING_Command *commands; | ||
41 | |||
42 | /** | ||
43 | * Interpreter task (if one is scheduled). | ||
44 | */ | ||
45 | struct GNUNET_SCHEDULER_Task *task; | ||
46 | |||
47 | /** | ||
48 | * Finish task of a blocking call to a commands finish method. | ||
49 | */ | ||
50 | struct GNUNET_SCHEDULER_Task *finish_task; | ||
51 | |||
52 | /** | ||
53 | * Our configuration. | ||
54 | */ | ||
55 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
56 | |||
57 | /** | ||
58 | * Task run on timeout. | ||
59 | */ | ||
60 | struct GNUNET_SCHEDULER_Task *timeout_task; | ||
61 | |||
62 | /** | ||
63 | * Instruction pointer. Tells #interpreter_run() which instruction to run | ||
64 | * next. Need (signed) int because it gets -1 when rewinding the | ||
65 | * interpreter to the first CMD. | ||
66 | */ | ||
67 | int ip; | ||
68 | |||
69 | /** | ||
70 | * Result of the testcases, #GNUNET_OK on success | ||
71 | */ | ||
72 | int result; | ||
73 | |||
74 | }; | ||
diff --git a/src/testing/testing_api_cmd_batch.c b/src/testing/testing_api_cmd_batch.c index 531778129..af260f80d 100644 --- a/src/testing/testing_api_cmd_batch.c +++ b/src/testing/testing_api_cmd_batch.c | |||
@@ -26,7 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | #include "platform.h" | 27 | #include "platform.h" |
28 | #include "gnunet_testing_ng_lib.h" | 28 | #include "gnunet_testing_ng_lib.h" |
29 | 29 | #include "testing.h" | |
30 | 30 | ||
31 | /** | 31 | /** |
32 | * State for a "batch" CMD. | 32 | * State for a "batch" CMD. |
@@ -70,7 +70,6 @@ batch_run (void *cls, | |||
70 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 70 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
71 | "Exiting from batch: %s\n", | 71 | "Exiting from batch: %s\n", |
72 | cmd->label); | 72 | cmd->label); |
73 | GNUNET_TESTING_interpreter_next (is); | ||
74 | return; | 73 | return; |
75 | } | 74 | } |
76 | bs->batch[bs->batch_ip].start_time | 75 | bs->batch[bs->batch_ip].start_time |
diff --git a/src/testing/testing_api_cmd_hello_world.c b/src/testing/testing_api_cmd_hello_world.c index 8c1d7353d..4347ac818 100644 --- a/src/testing/testing_api_cmd_hello_world.c +++ b/src/testing/testing_api_cmd_hello_world.c | |||
@@ -89,7 +89,6 @@ hello_world_run (void *cls, | |||
89 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 89 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
90 | "Now I am a %s\n", | 90 | "Now I am a %s\n", |
91 | hs->message); | 91 | hs->message); |
92 | GNUNET_TESTING_interpreter_next (is); | ||
93 | } | 92 | } |
94 | 93 | ||
95 | /** | 94 | /** |
diff --git a/src/testing/testing_api_cmd_hello_world_birth.c b/src/testing/testing_api_cmd_hello_world_birth.c index 0faf93cd8..2a5bded92 100644 --- a/src/testing/testing_api_cmd_hello_world_birth.c +++ b/src/testing/testing_api_cmd_hello_world_birth.c | |||
@@ -112,7 +112,6 @@ hello_world_birth_run (void *cls, | |||
112 | { | 112 | { |
113 | hbs->what_am_i = "boy!"; | 113 | hbs->what_am_i = "boy!"; |
114 | } | 114 | } |
115 | GNUNET_TESTING_interpreter_next (is); | ||
116 | } | 115 | } |
117 | 116 | ||
118 | /** | 117 | /** |
diff --git a/src/testing/testing_api_loop.c b/src/testing/testing_api_loop.c index f29329a60..dbd86ba90 100644 --- a/src/testing/testing_api_loop.c +++ b/src/testing/testing_api_loop.c | |||
@@ -28,10 +28,50 @@ | |||
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 "testing.h" | ||
31 | 32 | ||
32 | struct GNUNET_TESTING_Interpreter *is; | 33 | struct GNUNET_TESTING_Interpreter *is; |
33 | 34 | ||
34 | /** | 35 | /** |
36 | * Closure used to sync an asynchronous with an synchronous command. | ||
37 | */ | ||
38 | struct SyncTaskClosure | ||
39 | { | ||
40 | |||
41 | /** | ||
42 | * The asynchronous command the synchronous command waits for. | ||
43 | */ | ||
44 | const struct GNUNET_TESTING_Command *async_cmd; | ||
45 | |||
46 | /** | ||
47 | * The synchronous command that waits for the asynchronous command. | ||
48 | */ | ||
49 | const struct GNUNET_TESTING_Command *sync_cmd; | ||
50 | |||
51 | /** | ||
52 | * The interpreter of the test. | ||
53 | */ | ||
54 | struct GNUNET_TESTING_Interpreter *is; | ||
55 | }; | ||
56 | |||
57 | /** | ||
58 | * Closure used to run the finish task. | ||
59 | */ | ||
60 | struct FinishTaskClosure | ||
61 | { | ||
62 | |||
63 | /** | ||
64 | * The asynchronous command the synchronous command waits for. | ||
65 | */ | ||
66 | const struct GNUNET_TESTING_Command *cmd; | ||
67 | |||
68 | /** | ||
69 | * The interpreter of the test. | ||
70 | */ | ||
71 | struct GNUNET_TESTING_Interpreter *is; | ||
72 | }; | ||
73 | |||
74 | /** | ||
35 | * Lookup command by label. | 75 | * Lookup command by label. |
36 | * | 76 | * |
37 | * @param label label to look for | 77 | * @param label label to look for |
@@ -107,9 +147,10 @@ interpreter_run (void *cls); | |||
107 | /** | 147 | /** |
108 | * Current command is done, run the next one. | 148 | * Current command is done, run the next one. |
109 | */ | 149 | */ |
110 | void | 150 | static void |
111 | GNUNET_TESTING_interpreter_next (struct GNUNET_TESTING_Interpreter *is) | 151 | interpreter_next (void *cls) |
112 | { | 152 | { |
153 | struct GNUNET_TESTING_Interpreter *is = cls; | ||
113 | static unsigned long long ipc; | 154 | static unsigned long long ipc; |
114 | static struct GNUNET_TIME_Absolute last_report; | 155 | static struct GNUNET_TIME_Absolute last_report; |
115 | struct GNUNET_TESTING_Command *cmd = &is->commands[is->ip]; | 156 | struct GNUNET_TESTING_Command *cmd = &is->commands[is->ip]; |
@@ -141,6 +182,123 @@ GNUNET_TESTING_interpreter_next (struct GNUNET_TESTING_Interpreter *is) | |||
141 | } | 182 | } |
142 | 183 | ||
143 | 184 | ||
185 | static void | ||
186 | run_finish_task_next (void *cls) | ||
187 | { | ||
188 | struct FinishTaskClosure *ftc = cls; | ||
189 | const struct GNUNET_TESTING_Command *cmd = ftc->cmd; | ||
190 | struct GNUNET_TESTING_Interpreter *is = ftc->is; | ||
191 | |||
192 | if (cmd->finish (cmd->cls, &interpreter_next, is)) | ||
193 | { | ||
194 | is->finish_task = GNUNET_SCHEDULER_add_now (&run_finish_task_next, ftc); | ||
195 | } | ||
196 | else | ||
197 | { | ||
198 | is->finish_task = NULL; | ||
199 | } | ||
200 | |||
201 | } | ||
202 | |||
203 | |||
204 | static void | ||
205 | run_finish_task_sync (void *cls) | ||
206 | { | ||
207 | struct SyncTaskClosure *stc = cls; | ||
208 | const struct GNUNET_TESTING_Command *cmd = stc->async_cmd; | ||
209 | const struct GNUNET_TESTING_Command *sync_cmd = stc->sync_cmd; | ||
210 | struct FinishTaskClosure *ftc; | ||
211 | struct SyncState *sync_state = sync_cmd->cls; | ||
212 | struct GNUNET_SCHEDULER_Task *finish_task = sync_state->finish_task; | ||
213 | |||
214 | GNUNET_assert (NULL != finish_task); | ||
215 | ftc = GNUNET_new (struct FinishTaskClosure); | ||
216 | ftc->cmd = stc->sync_cmd; | ||
217 | ftc->is = stc->is; | ||
218 | struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); | ||
219 | if (cmd->default_timeout.rel_value_us < now.abs_value_us | ||
220 | - sync_state->start_finish_time.abs_value_us) | ||
221 | { | ||
222 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
223 | "The command with label %s did not finish its asyncronous task in time.\n", | ||
224 | cmd->label); | ||
225 | is->result = GNUNET_SYSERR; | ||
226 | GNUNET_SCHEDULER_shutdown (); | ||
227 | } | ||
228 | |||
229 | if (cmd->finish (cmd->cls, run_finish_task_next, ftc)) | ||
230 | { | ||
231 | finish_task = GNUNET_SCHEDULER_add_now (&run_finish_task_sync, stc); | ||
232 | } | ||
233 | else | ||
234 | { | ||
235 | finish_task = NULL; | ||
236 | } | ||
237 | } | ||
238 | |||
239 | |||
240 | static void | ||
241 | start_finish_on_ref (void *cls, | ||
242 | const struct GNUNET_TESTING_Command *cmd, | ||
243 | struct GNUNET_TESTING_Interpreter *is) | ||
244 | { | ||
245 | struct SyncState *sync_state = cls; | ||
246 | struct SyncTaskClosure *stc; | ||
247 | const struct GNUNET_TESTING_Command *async_cmd; | ||
248 | |||
249 | async_cmd = sync_state->async_cmd; | ||
250 | stc = GNUNET_new (struct SyncTaskClosure); | ||
251 | stc->async_cmd = async_cmd; | ||
252 | stc->sync_cmd = cmd; | ||
253 | stc->is = is; | ||
254 | sync_state->start_finish_time = GNUNET_TIME_absolute_get (); | ||
255 | sync_state->finish_task = GNUNET_SCHEDULER_add_now (&run_finish_task_sync, | ||
256 | stc); | ||
257 | } | ||
258 | |||
259 | |||
260 | const struct GNUNET_TESTING_Command | ||
261 | GNUNET_TESTING_cmd_finish (const char *finish_label, | ||
262 | const char *cmd_ref, | ||
263 | struct GNUNET_TIME_Relative timeout) | ||
264 | { | ||
265 | const struct GNUNET_TESTING_Command *async_cmd; | ||
266 | struct SyncState *sync_state; | ||
267 | |||
268 | async_cmd = GNUNET_TESTING_interpreter_lookup_command (cmd_ref); | ||
269 | sync_state = GNUNET_new (struct SyncState); | ||
270 | sync_state->async_cmd = async_cmd; | ||
271 | |||
272 | struct GNUNET_TESTING_Command cmd = { | ||
273 | .cls = sync_state, | ||
274 | .label = finish_label, | ||
275 | .run = &start_finish_on_ref, | ||
276 | .asynchronous_finish = GNUNET_NO | ||
277 | }; | ||
278 | |||
279 | return cmd; | ||
280 | } | ||
281 | |||
282 | |||
283 | const struct GNUNET_TESTING_Command | ||
284 | GNUNET_TESTING_cmd_make_asynchronous (const struct GNUNET_TESTING_Command cmd) | ||
285 | { | ||
286 | |||
287 | GNUNET_assert (NULL != cmd.finish); | ||
288 | const struct GNUNET_TESTING_Command async_cmd = { | ||
289 | .cls = cmd.cls, | ||
290 | .label = cmd.label, | ||
291 | .run = cmd.run, | ||
292 | .cleanup = cmd.cleanup, | ||
293 | .traits = cmd.traits, | ||
294 | .finish = cmd.finish, | ||
295 | .asynchronous_finish = GNUNET_YES | ||
296 | }; | ||
297 | |||
298 | return async_cmd; | ||
299 | } | ||
300 | |||
301 | |||
144 | /** | 302 | /** |
145 | * Current command failed, clean up and fail the test case. | 303 | * Current command failed, clean up and fail the test case. |
146 | * | 304 | * |
@@ -195,14 +353,15 @@ GNUNET_TESTING_interpreter_get_current_label (struct | |||
195 | 353 | ||
196 | 354 | ||
197 | /** | 355 | /** |
198 | * Run the main interpreter loop that performs exchange operations. | 356 | * Run the main interpreter loop. |
199 | * | 357 | * |
200 | * @param cls contains the `struct GNUNET_TESTING_Interpreter` | 358 | * @param cls contains the `struct GNUNET_TESTING_Interpreter` |
201 | */ | 359 | */ |
202 | static void | 360 | static void |
203 | interpreter_run (void *cls) | 361 | interpreter_run (void *cls) |
204 | { | 362 | { |
205 | (void) cls; | 363 | struct FinishTaskClosure *ftc; |
364 | struct GNUNET_TESTING_Interpreter *is = cls; | ||
206 | struct GNUNET_TESTING_Command *cmd = &is->commands[is->ip]; | 365 | struct GNUNET_TESTING_Command *cmd = &is->commands[is->ip]; |
207 | 366 | ||
208 | is->task = NULL; | 367 | is->task = NULL; |
@@ -227,6 +386,17 @@ interpreter_run (void *cls) | |||
227 | cmd->run (cmd->cls, | 386 | cmd->run (cmd->cls, |
228 | cmd, | 387 | cmd, |
229 | is); | 388 | is); |
389 | if ((NULL != cmd->finish) && (GNUNET_NO == cmd->asynchronous_finish)) | ||
390 | { | ||
391 | ftc = GNUNET_new (struct FinishTaskClosure); | ||
392 | ftc->cmd = cmd; | ||
393 | ftc->is = is; | ||
394 | cmd->finish_task = GNUNET_SCHEDULER_add_now (run_finish_task_next, ftc); | ||
395 | } | ||
396 | else | ||
397 | { | ||
398 | interpreter_next (is); | ||
399 | } | ||
230 | } | 400 | } |
231 | 401 | ||
232 | 402 | ||
@@ -253,9 +423,15 @@ do_shutdown (void *cls) | |||
253 | 423 | ||
254 | for (unsigned int j = 0; | 424 | for (unsigned int j = 0; |
255 | NULL != (cmd = &is->commands[j])->label; | 425 | NULL != (cmd = &is->commands[j])->label; |
256 | j++) | 426 | j++) { |
257 | cmd->cleanup (cmd->cls, | 427 | cmd->cleanup (cmd->cls, |
258 | cmd); | 428 | cmd); |
429 | if (NULL != cmd->finish_task) | ||
430 | { | ||
431 | GNUNET_SCHEDULER_cancel (cmd->finish_task); | ||
432 | cmd->finish_task = NULL; | ||
433 | } | ||
434 | } | ||
259 | 435 | ||
260 | if (NULL != is->task) | 436 | if (NULL != is->task) |
261 | { | 437 | { |
diff --git a/src/transport/transport-testing-ng.h b/src/transport/transport-testing-ng.h new file mode 100644 index 000000000..cd5ba65a9 --- /dev/null +++ b/src/transport/transport-testing-ng.h | |||
@@ -0,0 +1,71 @@ | |||
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 | * @author t3sserakt | ||
23 | */ | ||
24 | |||
25 | struct TngState | ||
26 | { | ||
27 | /** | ||
28 | * Handle to operation | ||
29 | */ | ||
30 | struct GNUNET_TESTBED_Operation *operation; | ||
31 | |||
32 | /** | ||
33 | * Flag indicating if service is ready. | ||
34 | */ | ||
35 | int service_ready; | ||
36 | |||
37 | /** | ||
38 | * Abort task identifier | ||
39 | */ | ||
40 | struct GNUNET_SCHEDULER_Task *abort_task; | ||
41 | |||
42 | /** | ||
43 | * Label of peer command. | ||
44 | */ | ||
45 | const char *peer_label; | ||
46 | |||
47 | /** | ||
48 | * Name of service to start. | ||
49 | */ | ||
50 | const char *servicename; | ||
51 | |||
52 | /** | ||
53 | * Peer identity of the system. | ||
54 | */ | ||
55 | struct GNUNET_PeerIdentity *peer_identity; | ||
56 | |||
57 | /** | ||
58 | * Message handler for transport service. | ||
59 | */ | ||
60 | const struct GNUNET_MQ_MessageHandler *handlers; | ||
61 | |||
62 | /** | ||
63 | * Notify connect callback | ||
64 | */ | ||
65 | GNUNET_TRANSPORT_NotifyConnect nc; | ||
66 | |||
67 | /** | ||
68 | * Closure for the @a nc callback | ||
69 | */ | ||
70 | void *cb_cls; | ||
71 | }; | ||