aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authort3sserakt <t3ss@posteo.de>2021-04-15 15:35:28 +0200
committert3sserakt <t3ss@posteo.de>2021-04-15 15:35:28 +0200
commit925c210d978cd0e3dfc718d9e4c65ad713a817b9 (patch)
treeb769182d686220816a387336d525f37124dbad72 /src
parenta785d16b7f49947458782f65f344036a848f4ac7 (diff)
downloadgnunet-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)
Diffstat (limited to 'src')
-rw-r--r--src/include/gnunet_testbed_ng_service.h35
-rw-r--r--src/include/gnunet_testing_ng_lib.h104
-rw-r--r--src/testbed/testbed_api_cmd_controller.c1
-rw-r--r--src/testbed/testbed_api_cmd_peer.c40
-rw-r--r--src/testbed/testbed_api_cmd_peer_store.c60
-rw-r--r--src/testbed/testbed_api_cmd_service.c140
-rw-r--r--src/testbed/testbed_api_cmd_tng_connect.c55
-rw-r--r--src/testbed/testbed_api_cmd_tng_service.c276
-rw-r--r--src/testing/testing.h74
-rw-r--r--src/testing/testing_api_cmd_batch.c3
-rw-r--r--src/testing/testing_api_cmd_hello_world.c1
-rw-r--r--src/testing/testing_api_cmd_hello_world_birth.c1
-rw-r--r--src/testing/testing_api_loop.c186
-rw-r--r--src/transport/transport-testing-ng.h71
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
41struct ServiceState 41struct 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
69struct PeerCmdState 43struct 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
242GNUNET_TESTBED_shutdown_peer (struct PeerCmdState *ps); 211GNUNET_TESTBED_shutdown_peer (struct PeerCmdState *ps);
243 212
244void 213void
245GNUNET_TESTBED_shutdown_service (struct ServiceState *ss); 214GNUNET_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, 54struct GNUNET_TESTING_Interpreter;
55// say main loop and a few select commands, like next/fail/batch); + helper
56// function to access 'cfg'?
57struct 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 */
192struct 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 */
251void
252GNUNET_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!)
280const struct GNUNET_TESTING_Command 261const struct GNUNET_TESTING_Command
281TALER_TESTING_cmd_make_asynchronous (const struct GNUNET_TESTING_Command cmd); 262GNUNET_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!)
296const struct GNUNET_TESTING_Command 276const struct GNUNET_TESTING_Command
297TALER_TESTING_cmd_finish (const char *finish_label, 277GNUNET_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 */
83int
84GNUNET_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
28static void
29service_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
40struct GNUNET_TESTING_Command
41GNUNET_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 */
46static void
47do_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*/
65static void
66service_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*/
81static int
82service_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
91static void
92service_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 */
112void
113GNUNET_TESTBED_shutdown_service (struct ServiceState *cs)
114{
115 LOG (GNUNET_ERROR_TYPE_DEBUG,
116 "Shutting down...\n");
117}
118
119
120struct GNUNET_TESTING_Command
121GNUNET_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
29static void
30tng_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
39struct GNUNET_TESTING_Command
40GNUNET_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 */
46static void
47do_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*/
65static void
66tng_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*/
81static int
82tng_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
92static void *
93notify_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
111static void
112notify_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 */
131static void *
132connect_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 &notify_connect,
142 &notify_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 */
154static void
155disconnect_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 */
169static void
170service_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 */
196static void
197pi_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
214static void
215tng_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 */
240void
241GNUNET_TESTBED_shutdown_service (struct TngState *cs)
242{
243 LOG (GNUNET_ERROR_TYPE_DEBUG,
244 "Shutting down...\n");
245}
246
247
248struct GNUNET_TESTING_Command
249GNUNET_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'?
34struct 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
32struct GNUNET_TESTING_Interpreter *is; 33struct GNUNET_TESTING_Interpreter *is;
33 34
34/** 35/**
36 * Closure used to sync an asynchronous with an synchronous command.
37 */
38struct 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*/
60struct 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 */
110void 150static void
111GNUNET_TESTING_interpreter_next (struct GNUNET_TESTING_Interpreter *is) 151interpreter_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
185static void
186run_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
204static void
205run_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
240static void
241start_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
260const struct GNUNET_TESTING_Command
261GNUNET_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
283const struct GNUNET_TESTING_Command
284GNUNET_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 */
202static void 360static void
203interpreter_run (void *cls) 361interpreter_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
25struct 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};