diff options
Diffstat (limited to 'src/cadet/cadet_test_lib.c')
-rw-r--r-- | src/cadet/cadet_test_lib.c | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/src/cadet/cadet_test_lib.c b/src/cadet/cadet_test_lib.c new file mode 100644 index 000000000..663972cad --- /dev/null +++ b/src/cadet/cadet_test_lib.c | |||
@@ -0,0 +1,295 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2012 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file cadet/cadet_test_lib.c | ||
22 | * @author Bartlomiej Polot | ||
23 | * @brief library for writing CADET tests | ||
24 | */ | ||
25 | #include "platform.h" | ||
26 | #include "gnunet_util_lib.h" | ||
27 | #include "cadet_test_lib.h" | ||
28 | #include "gnunet_cadet_service.h" | ||
29 | |||
30 | /** | ||
31 | * Test context for a CADET Test. | ||
32 | */ | ||
33 | struct GNUNET_CADET_TEST_Context | ||
34 | { | ||
35 | /** | ||
36 | * Array of running peers. | ||
37 | */ | ||
38 | struct GNUNET_TESTBED_Peer **peers; | ||
39 | |||
40 | /** | ||
41 | * Array of handles to the CADET for each peer. | ||
42 | */ | ||
43 | struct GNUNET_CADET_Handle **cadetes; | ||
44 | |||
45 | /** | ||
46 | * Operation associated with the connection to the CADET. | ||
47 | */ | ||
48 | struct GNUNET_TESTBED_Operation **ops; | ||
49 | |||
50 | /** | ||
51 | * Main function of the test to run once all CADETs are available. | ||
52 | */ | ||
53 | GNUNET_CADET_TEST_AppMain app_main; | ||
54 | |||
55 | /** | ||
56 | * Closure for 'app_main'. | ||
57 | */ | ||
58 | void *app_main_cls; | ||
59 | |||
60 | /** | ||
61 | * Number of peers running, size of the arrays above. | ||
62 | */ | ||
63 | unsigned int num_peers; | ||
64 | |||
65 | /** | ||
66 | * Handler for incoming tunnels. | ||
67 | */ | ||
68 | GNUNET_CADET_InboundChannelNotificationHandler *new_channel; | ||
69 | |||
70 | /** | ||
71 | * Cleaner for destroyed incoming tunnels. | ||
72 | */ | ||
73 | GNUNET_CADET_ChannelEndHandler *cleaner; | ||
74 | |||
75 | /** | ||
76 | * Message handlers. | ||
77 | */ | ||
78 | struct GNUNET_CADET_MessageHandler* handlers; | ||
79 | |||
80 | /** | ||
81 | * Application ports. | ||
82 | */ | ||
83 | const uint32_t *ports; | ||
84 | |||
85 | }; | ||
86 | |||
87 | |||
88 | /** | ||
89 | * Context for a cadet adapter callback. | ||
90 | */ | ||
91 | struct GNUNET_CADET_TEST_AdapterContext | ||
92 | { | ||
93 | /** | ||
94 | * Peer number for the particular peer. | ||
95 | */ | ||
96 | unsigned int peer; | ||
97 | |||
98 | /** | ||
99 | * General context. | ||
100 | */ | ||
101 | struct GNUNET_CADET_TEST_Context *ctx; | ||
102 | }; | ||
103 | |||
104 | |||
105 | /** | ||
106 | * Adapter function called to establish a connection to | ||
107 | * the CADET service. | ||
108 | * | ||
109 | * @param cls closure | ||
110 | * @param cfg configuration of the peer to connect to; will be available until | ||
111 | * GNUNET_TESTBED_operation_done() is called on the operation returned | ||
112 | * from GNUNET_TESTBED_service_connect() | ||
113 | * @return service handle to return in 'op_result', NULL on error | ||
114 | */ | ||
115 | static void * | ||
116 | cadet_connect_adapter (void *cls, | ||
117 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
118 | { | ||
119 | struct GNUNET_CADET_TEST_AdapterContext *actx = cls; | ||
120 | struct GNUNET_CADET_TEST_Context *ctx = actx->ctx; | ||
121 | struct GNUNET_CADET_Handle *h; | ||
122 | |||
123 | h = GNUNET_CADET_connect (cfg, | ||
124 | (void *) (long) actx->peer, | ||
125 | ctx->new_channel, | ||
126 | ctx->cleaner, | ||
127 | ctx->handlers, | ||
128 | ctx->ports); | ||
129 | return h; | ||
130 | } | ||
131 | |||
132 | |||
133 | /** | ||
134 | * Adapter function called to destroy a connection to | ||
135 | * the CADET service. | ||
136 | * | ||
137 | * @param cls closure | ||
138 | * @param op_result service handle returned from the connect adapter | ||
139 | */ | ||
140 | static void | ||
141 | cadet_disconnect_adapter (void *cls, | ||
142 | void *op_result) | ||
143 | { | ||
144 | struct GNUNET_CADET_Handle *cadet = op_result; | ||
145 | struct GNUNET_CADET_TEST_AdapterContext *actx = cls; | ||
146 | |||
147 | GNUNET_free (actx); | ||
148 | GNUNET_CADET_disconnect (cadet); | ||
149 | } | ||
150 | |||
151 | |||
152 | /** | ||
153 | * Callback to be called when a service connect operation is completed. | ||
154 | * | ||
155 | * @param cls The callback closure from functions generating an operation. | ||
156 | * @param op The operation that has been finished. | ||
157 | * @param ca_result The service handle returned from | ||
158 | * GNUNET_TESTBED_ConnectAdapter() (cadet handle). | ||
159 | * @param emsg Error message in case the operation has failed. | ||
160 | * NULL if operation has executed successfully. | ||
161 | */ | ||
162 | static void | ||
163 | cadet_connect_cb (void *cls, | ||
164 | struct GNUNET_TESTBED_Operation *op, | ||
165 | void *ca_result, | ||
166 | const char *emsg) | ||
167 | { | ||
168 | struct GNUNET_CADET_TEST_Context *ctx = cls; | ||
169 | unsigned int i; | ||
170 | |||
171 | if (NULL != emsg) | ||
172 | { | ||
173 | fprintf (stderr, "Failed to connect to CADET service: %s\n", | ||
174 | emsg); | ||
175 | GNUNET_SCHEDULER_shutdown (); | ||
176 | return; | ||
177 | } | ||
178 | for (i = 0; i < ctx->num_peers; i++) | ||
179 | if (op == ctx->ops[i]) | ||
180 | { | ||
181 | ctx->cadetes[i] = ca_result; | ||
182 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "...cadet %u connected\n", i); | ||
183 | } | ||
184 | for (i = 0; i < ctx->num_peers; i++) | ||
185 | if (NULL == ctx->cadetes[i]) | ||
186 | return; /* still some CADET connections missing */ | ||
187 | /* all CADET connections ready! */ | ||
188 | ctx->app_main (ctx->app_main_cls, | ||
189 | ctx, | ||
190 | ctx->num_peers, | ||
191 | ctx->peers, | ||
192 | ctx->cadetes); | ||
193 | } | ||
194 | |||
195 | |||
196 | void | ||
197 | GNUNET_CADET_TEST_cleanup (struct GNUNET_CADET_TEST_Context *ctx) | ||
198 | { | ||
199 | unsigned int i; | ||
200 | |||
201 | for (i = 0; i < ctx->num_peers; i++) | ||
202 | { | ||
203 | GNUNET_assert (NULL != ctx->ops[i]); | ||
204 | GNUNET_TESTBED_operation_done (ctx->ops[i]); | ||
205 | ctx->ops[i] = NULL; | ||
206 | } | ||
207 | GNUNET_free (ctx->ops); | ||
208 | GNUNET_free (ctx->cadetes); | ||
209 | GNUNET_free (ctx); | ||
210 | GNUNET_SCHEDULER_shutdown (); | ||
211 | } | ||
212 | |||
213 | |||
214 | /** | ||
215 | * Callback run when the testbed is ready (peers running and connected to | ||
216 | * each other) | ||
217 | * | ||
218 | * @param cls Closure (context). | ||
219 | * @param h the run handle | ||
220 | * @param num_peers Number of peers that are running. | ||
221 | * @param peers Handles to each one of the @c num_peers peers. | ||
222 | * @param links_succeeded the number of overlay link connection attempts that | ||
223 | * succeeded | ||
224 | * @param links_failed the number of overlay link connection attempts that | ||
225 | * failed | ||
226 | */ | ||
227 | static void | ||
228 | cadet_test_run (void *cls, | ||
229 | struct GNUNET_TESTBED_RunHandle *h, | ||
230 | unsigned int num_peers, | ||
231 | struct GNUNET_TESTBED_Peer **peers, | ||
232 | unsigned int links_succeeded, | ||
233 | unsigned int links_failed) | ||
234 | { | ||
235 | struct GNUNET_CADET_TEST_Context *ctx = cls; | ||
236 | unsigned int i; | ||
237 | |||
238 | if (num_peers != ctx->num_peers) | ||
239 | { | ||
240 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Peers started %u/%u, ending\n", | ||
241 | num_peers, ctx->num_peers); | ||
242 | exit (1); | ||
243 | } | ||
244 | ctx->peers = peers; | ||
245 | for (i = 0; i < num_peers; i++) | ||
246 | { | ||
247 | struct GNUNET_CADET_TEST_AdapterContext *newctx; | ||
248 | newctx = GNUNET_new (struct GNUNET_CADET_TEST_AdapterContext); | ||
249 | newctx->peer = i; | ||
250 | newctx->ctx = ctx; | ||
251 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connecting to cadet %u\n", i); | ||
252 | ctx->ops[i] = GNUNET_TESTBED_service_connect (ctx, | ||
253 | peers[i], | ||
254 | "cadet", | ||
255 | &cadet_connect_cb, | ||
256 | ctx, | ||
257 | &cadet_connect_adapter, | ||
258 | &cadet_disconnect_adapter, | ||
259 | newctx); | ||
260 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "op handle %p\n", ctx->ops[i]); | ||
261 | } | ||
262 | } | ||
263 | |||
264 | |||
265 | void | ||
266 | GNUNET_CADET_TEST_run (const char *testname, | ||
267 | const char *cfgname, | ||
268 | unsigned int num_peers, | ||
269 | GNUNET_CADET_TEST_AppMain tmain, | ||
270 | void *tmain_cls, | ||
271 | GNUNET_CADET_InboundChannelNotificationHandler new_channel, | ||
272 | GNUNET_CADET_ChannelEndHandler cleaner, | ||
273 | struct GNUNET_CADET_MessageHandler* handlers, | ||
274 | const uint32_t *ports) | ||
275 | { | ||
276 | struct GNUNET_CADET_TEST_Context *ctx; | ||
277 | |||
278 | ctx = GNUNET_new (struct GNUNET_CADET_TEST_Context); | ||
279 | ctx->num_peers = num_peers; | ||
280 | ctx->ops = GNUNET_malloc (num_peers * sizeof (struct GNUNET_TESTBED_Operation *)); | ||
281 | ctx->cadetes = GNUNET_malloc (num_peers * sizeof (struct GNUNET_CADET_Handle *)); | ||
282 | ctx->app_main = tmain; | ||
283 | ctx->app_main_cls = tmain_cls; | ||
284 | ctx->new_channel = new_channel; | ||
285 | ctx->cleaner = cleaner; | ||
286 | ctx->handlers = handlers; | ||
287 | ctx->ports = ports; | ||
288 | GNUNET_TESTBED_test_run (testname, | ||
289 | cfgname, | ||
290 | num_peers, | ||
291 | 0LL, NULL, NULL, | ||
292 | &cadet_test_run, ctx); | ||
293 | } | ||
294 | |||
295 | /* end of cadet_test_lib.c */ | ||