diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-09-09 13:28:48 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-09-09 13:28:48 +0000 |
commit | 9d732bb204de9177aad6ae70c910cbf2615d81a3 (patch) | |
tree | 44ddd6e9e1dad749db51003acfa46d7835593dc6 /src/fs/fs_test_lib.c | |
parent | a1d7926951beb7466a1462e43b9933530e5825f7 (diff) | |
download | gnunet-9d732bb204de9177aad6ae70c910cbf2615d81a3.tar.gz gnunet-9d732bb204de9177aad6ae70c910cbf2615d81a3.zip |
make fs tests build against new testbed library -- they do not pass yet
Diffstat (limited to 'src/fs/fs_test_lib.c')
-rw-r--r-- | src/fs/fs_test_lib.c | 892 |
1 files changed, 404 insertions, 488 deletions
diff --git a/src/fs/fs_test_lib.c b/src/fs/fs_test_lib.c index 06ab01f8d..bbed98249 100644 --- a/src/fs/fs_test_lib.c +++ b/src/fs/fs_test_lib.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2010, 2011 Christian Grothoff (and other contributing authors) | 3 | (C) 2010, 2011, 2012 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 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 | 6 | it under the terms of the GNU General Public License as published |
@@ -20,8 +20,8 @@ | |||
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @file fs/fs_test_lib.c | 22 | * @file fs/fs_test_lib.c |
23 | * @brief library routines for testing FS publishing and downloading | 23 | * @brief library routines for testing FS publishing and downloading; |
24 | * with multiple peers; this code is limited to flat files | 24 | * this code is limited to flat files |
25 | * and no keywords (those functions can be tested with | 25 | * and no keywords (those functions can be tested with |
26 | * single-peer setups; this is for testing routing). | 26 | * single-peer setups; this is for testing routing). |
27 | * @author Christian Grothoff | 27 | * @author Christian Grothoff |
@@ -29,23 +29,21 @@ | |||
29 | #include "platform.h" | 29 | #include "platform.h" |
30 | #include "fs_api.h" | 30 | #include "fs_api.h" |
31 | #include "fs_test_lib.h" | 31 | #include "fs_test_lib.h" |
32 | #include "gnunet_testing_lib.h" | ||
33 | 32 | ||
34 | #define CONNECT_ATTEMPTS 4 | ||
35 | 33 | ||
36 | #define CONTENT_LIFETIME GNUNET_TIME_UNIT_HOURS | 34 | #define CONTENT_LIFETIME GNUNET_TIME_UNIT_HOURS |
37 | 35 | ||
36 | |||
38 | /** | 37 | /** |
39 | * Handle for a daemon started for testing FS. | 38 | * Handle for a publishing operation started for testing FS. |
40 | */ | 39 | */ |
41 | struct GNUNET_FS_TestDaemon | 40 | struct TestPublishOperation |
42 | { | 41 | { |
43 | 42 | ||
44 | /** | 43 | /** |
45 | * Global configuration, only stored in first test daemon, | 44 | * Handle for the operation to connect to the peer's 'fs' service. |
46 | * otherwise NULL. | ||
47 | */ | 45 | */ |
48 | struct GNUNET_CONFIGURATION_Handle *gcfg; | 46 | struct GNUNET_TESTBED_Operation *fs_op; |
49 | 47 | ||
50 | /** | 48 | /** |
51 | * Handle to the file sharing context using this daemon. | 49 | * Handle to the file sharing context using this daemon. |
@@ -53,27 +51,6 @@ struct GNUNET_FS_TestDaemon | |||
53 | struct GNUNET_FS_Handle *fs; | 51 | struct GNUNET_FS_Handle *fs; |
54 | 52 | ||
55 | /** | 53 | /** |
56 | * Handle to the daemon via testing. | ||
57 | */ | ||
58 | struct GNUNET_TESTING_Daemon *daemon; | ||
59 | |||
60 | /** | ||
61 | * Note that 'group' will be the same value for all of the | ||
62 | * daemons started jointly. | ||
63 | */ | ||
64 | struct GNUNET_TESTING_PeerGroup *group; | ||
65 | |||
66 | /** | ||
67 | * Configuration for accessing this peer. | ||
68 | */ | ||
69 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
70 | |||
71 | /** | ||
72 | * ID of this peer. | ||
73 | */ | ||
74 | struct GNUNET_PeerIdentity id; | ||
75 | |||
76 | /** | ||
77 | * Function to call when upload is done. | 54 | * Function to call when upload is done. |
78 | */ | 55 | */ |
79 | GNUNET_FS_TEST_UriContinuation publish_cont; | 56 | GNUNET_FS_TEST_UriContinuation publish_cont; |
@@ -109,6 +86,49 @@ struct GNUNET_FS_TestDaemon | |||
109 | char *publish_tmp_file; | 86 | char *publish_tmp_file; |
110 | 87 | ||
111 | /** | 88 | /** |
89 | * Size of the file. | ||
90 | */ | ||
91 | uint64_t size; | ||
92 | |||
93 | /** | ||
94 | * Anonymity level used. | ||
95 | */ | ||
96 | uint32_t anonymity; | ||
97 | |||
98 | /** | ||
99 | * Verbosity level of the current operation. | ||
100 | */ | ||
101 | unsigned int verbose; | ||
102 | |||
103 | /** | ||
104 | * Are we testing indexing? (YES: index, NO: insert, SYSERR: simulate) | ||
105 | */ | ||
106 | int do_index; | ||
107 | }; | ||
108 | |||
109 | |||
110 | /** | ||
111 | * Handle for a download operation started for testing FS. | ||
112 | */ | ||
113 | struct TestDownloadOperation | ||
114 | { | ||
115 | |||
116 | /** | ||
117 | * Handle for the operation to connect to the peer's 'fs' service. | ||
118 | */ | ||
119 | struct GNUNET_TESTBED_Operation *fs_op; | ||
120 | |||
121 | /** | ||
122 | * Handle to the file sharing context using this daemon. | ||
123 | */ | ||
124 | struct GNUNET_FS_Handle *fs; | ||
125 | |||
126 | /** | ||
127 | * Handle to the daemon via testing. | ||
128 | */ | ||
129 | struct GNUNET_TESTING_Daemon *daemon; | ||
130 | |||
131 | /** | ||
112 | * Function to call when download is done. | 132 | * Function to call when download is done. |
113 | */ | 133 | */ |
114 | GNUNET_SCHEDULER_Task download_cont; | 134 | GNUNET_SCHEDULER_Task download_cont; |
@@ -119,9 +139,9 @@ struct GNUNET_FS_TestDaemon | |||
119 | void *download_cont_cls; | 139 | void *download_cont_cls; |
120 | 140 | ||
121 | /** | 141 | /** |
122 | * Seed for download verification. | 142 | * URI to download. |
123 | */ | 143 | */ |
124 | uint32_t download_seed; | 144 | struct GNUNET_FS_Uri *uri; |
125 | 145 | ||
126 | /** | 146 | /** |
127 | * Task to abort downloading (timeout). | 147 | * Task to abort downloading (timeout). |
@@ -134,107 +154,108 @@ struct GNUNET_FS_TestDaemon | |||
134 | struct GNUNET_FS_DownloadContext *download_context; | 154 | struct GNUNET_FS_DownloadContext *download_context; |
135 | 155 | ||
136 | /** | 156 | /** |
137 | * Verbosity level of the current operation. | 157 | * Size of the file. |
138 | */ | 158 | */ |
139 | int verbose; | 159 | uint64_t size; |
140 | 160 | ||
161 | /** | ||
162 | * Anonymity level used. | ||
163 | */ | ||
164 | uint32_t anonymity; | ||
141 | 165 | ||
142 | }; | 166 | /** |
167 | * Seed for download verification. | ||
168 | */ | ||
169 | uint32_t download_seed; | ||
143 | 170 | ||
144 | /** | 171 | /** |
145 | * Check whether peers successfully shut down. | 172 | * Verbosity level of the current operation. |
146 | */ | 173 | */ |
147 | static void | 174 | unsigned int verbose; |
148 | shutdown_callback (void *cls, const char *emsg) | ||
149 | { | ||
150 | struct GNUNET_CONFIGURATION_Handle *gcfg = cls; | ||
151 | 175 | ||
152 | if (emsg != NULL) | 176 | }; |
153 | { | ||
154 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Shutdown of peers failed: %s\n", | ||
155 | emsg); | ||
156 | } | ||
157 | else | ||
158 | { | ||
159 | #if VERBOSE | ||
160 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All peers successfully shut down!\n"); | ||
161 | #endif | ||
162 | } | ||
163 | if (gcfg != NULL) | ||
164 | GNUNET_CONFIGURATION_destroy (gcfg); | ||
165 | } | ||
166 | 177 | ||
167 | 178 | ||
179 | /** | ||
180 | * Task scheduled to report on the completion of our publish operation. | ||
181 | * | ||
182 | * @param cls the publish operation context | ||
183 | * @param tc scheduler context (unused) | ||
184 | */ | ||
168 | static void | 185 | static void |
169 | report_uri (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 186 | report_uri (void *cls, |
187 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
170 | { | 188 | { |
171 | struct GNUNET_FS_TestDaemon *daemon = cls; | 189 | struct TestPublishOperation *po = cls; |
172 | GNUNET_FS_TEST_UriContinuation cont; | 190 | |
173 | struct GNUNET_FS_Uri *uri; | 191 | GNUNET_FS_publish_stop (po->publish_context); |
174 | 192 | GNUNET_TESTBED_operation_done (po->fs_op); | |
175 | GNUNET_FS_publish_stop (daemon->publish_context); | 193 | po->publish_cont (po->publish_cont_cls, po->publish_uri); |
176 | daemon->publish_context = NULL; | 194 | GNUNET_FS_uri_destroy (po->publish_uri); |
177 | cont = daemon->publish_cont; | 195 | GNUNET_free_non_null (po->publish_tmp_file); |
178 | daemon->publish_cont = NULL; | 196 | GNUNET_free (po); |
179 | uri = daemon->publish_uri; | ||
180 | cont (daemon->publish_cont_cls, uri); | ||
181 | GNUNET_FS_uri_destroy (uri); | ||
182 | } | 197 | } |
183 | 198 | ||
184 | 199 | ||
200 | /** | ||
201 | * Task scheduled to run when publish operation times out. | ||
202 | * | ||
203 | * @param cls the publish operation context | ||
204 | * @param tc scheduler context (unused) | ||
205 | */ | ||
185 | static void | 206 | static void |
186 | report_success (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 207 | publish_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
187 | { | 208 | { |
188 | struct GNUNET_FS_TestDaemon *daemon = cls; | 209 | struct TestPublishOperation *po = cls; |
189 | 210 | ||
190 | GNUNET_FS_download_stop (daemon->download_context, GNUNET_YES); | 211 | po->publish_timeout_task = GNUNET_SCHEDULER_NO_TASK; |
191 | daemon->download_context = NULL; | 212 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
192 | GNUNET_SCHEDULER_add_continuation (daemon->download_cont, | 213 | "Timeout while trying to publish data\n"); |
193 | daemon->download_cont_cls, | 214 | if (NULL == po->fs) |
194 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | 215 | GNUNET_TESTBED_operation_cancel (po->fs_op); |
195 | daemon->download_cont = NULL; | 216 | else |
217 | GNUNET_TESTBED_operation_done (po->fs_op); | ||
218 | GNUNET_FS_publish_stop (po->publish_context); | ||
219 | GNUNET_TESTBED_operation_done (po->fs_op); | ||
220 | po->publish_cont (po->publish_cont_cls, NULL); | ||
221 | GNUNET_free_non_null (po->publish_tmp_file); | ||
222 | GNUNET_free (po); | ||
196 | } | 223 | } |
197 | 224 | ||
198 | 225 | ||
226 | /** | ||
227 | * Progress callback for file-sharing events while publishing. | ||
228 | * | ||
229 | * @param cls the publish operation context | ||
230 | * @param info information about the event | ||
231 | */ | ||
199 | static void * | 232 | static void * |
200 | progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) | 233 | publish_progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) |
201 | { | 234 | { |
202 | struct GNUNET_FS_TestDaemon *daemon = cls; | 235 | struct TestPublishOperation *po = cls; |
203 | 236 | ||
204 | switch (info->status) | 237 | switch (info->status) |
205 | { | 238 | { |
206 | case GNUNET_FS_STATUS_PUBLISH_COMPLETED: | 239 | case GNUNET_FS_STATUS_PUBLISH_COMPLETED: |
207 | GNUNET_SCHEDULER_cancel (daemon->publish_timeout_task); | 240 | GNUNET_SCHEDULER_cancel (po->publish_timeout_task); |
208 | daemon->publish_timeout_task = GNUNET_SCHEDULER_NO_TASK; | 241 | po->publish_timeout_task = GNUNET_SCHEDULER_NO_TASK; |
209 | daemon->publish_uri = | 242 | po->publish_uri = |
210 | GNUNET_FS_uri_dup (info->value.publish.specifics.completed.chk_uri); | 243 | GNUNET_FS_uri_dup (info->value.publish.specifics.completed.chk_uri); |
211 | GNUNET_SCHEDULER_add_continuation (&report_uri, daemon, | 244 | GNUNET_SCHEDULER_add_continuation (&report_uri, po, |
212 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | 245 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); |
213 | break; | 246 | break; |
214 | case GNUNET_FS_STATUS_PUBLISH_PROGRESS: | 247 | case GNUNET_FS_STATUS_PUBLISH_PROGRESS: |
215 | if (daemon->verbose) | 248 | if (po->verbose) |
216 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Publishing at %llu/%llu bytes\n", | 249 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Publishing at %llu/%llu bytes\n", |
217 | (unsigned long long) info->value.publish.completed, | 250 | (unsigned long long) info->value.publish.completed, |
218 | (unsigned long long) info->value.publish.size); | 251 | (unsigned long long) info->value.publish.size); |
219 | break; | 252 | break; |
220 | case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS: | 253 | case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS: |
221 | if (daemon->verbose) | 254 | if (po->verbose) |
222 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Download at %llu/%llu bytes\n", | 255 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Download at %llu/%llu bytes\n", |
223 | (unsigned long long) info->value.download.completed, | 256 | (unsigned long long) info->value.download.completed, |
224 | (unsigned long long) info->value.download.size); | 257 | (unsigned long long) info->value.download.size); |
225 | break; | 258 | break; |
226 | case GNUNET_FS_STATUS_DOWNLOAD_COMPLETED: | ||
227 | GNUNET_SCHEDULER_cancel (daemon->download_timeout_task); | ||
228 | daemon->download_timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
229 | GNUNET_SCHEDULER_add_continuation (&report_success, daemon, | ||
230 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | ||
231 | break; | ||
232 | case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE: | ||
233 | case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE: | ||
234 | break; | ||
235 | /* FIXME: monitor data correctness during download progress */ | ||
236 | /* FIXME: do performance reports given sufficient verbosity */ | ||
237 | /* FIXME: advance timeout task to "immediate" on error */ | ||
238 | default: | 259 | default: |
239 | break; | 260 | break; |
240 | } | 261 | } |
@@ -242,460 +263,347 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) | |||
242 | } | 263 | } |
243 | 264 | ||
244 | 265 | ||
245 | struct StartContext | 266 | /** |
246 | { | 267 | * Generate test data for publishing test. |
247 | struct GNUNET_TIME_Relative timeout; | 268 | * |
248 | unsigned int total; | 269 | * @param cls pointer to uint32_t with publishing seed |
249 | unsigned int have; | 270 | * @param offset offset to generate data for |
250 | struct GNUNET_FS_TestDaemon **daemons; | 271 | * @param max maximum number of bytes to generate |
251 | GNUNET_SCHEDULER_Task cont; | 272 | * @param buf where to write generated data |
252 | void *cont_cls; | 273 | * @param emsg where to store error message (unused) |
253 | struct GNUNET_TESTING_PeerGroup *group; | 274 | * @return number of bytes written to buf |
254 | struct GNUNET_CONFIGURATION_Handle *cfg; | 275 | */ |
255 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; | 276 | static size_t |
256 | }; | 277 | file_generator (void *cls, |
257 | 278 | uint64_t offset, | |
258 | 279 | size_t max, | |
259 | static void | 280 | void *buf, |
260 | notify_running (void *cls, const struct GNUNET_PeerIdentity *id, | 281 | char **emsg) |
261 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
262 | struct GNUNET_TESTING_Daemon *d, const char *emsg) | ||
263 | { | 282 | { |
264 | struct StartContext *sctx = cls; | 283 | uint32_t *publish_seed = cls; |
265 | unsigned int i; | 284 | uint64_t pos; |
285 | uint8_t *cbuf = buf; | ||
286 | int mod; | ||
266 | 287 | ||
267 | if (emsg != NULL) | 288 | if (emsg != NULL) |
289 | *emsg = NULL; | ||
290 | if (buf == NULL) | ||
291 | return 0; | ||
292 | for (pos = 0; pos < 8; pos++) | ||
293 | cbuf[pos] = (uint8_t) (offset >> pos * 8); | ||
294 | for (pos = 8; pos < max; pos++) | ||
268 | { | 295 | { |
269 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to start daemon: %s\n"), | 296 | mod = (255 - (offset / 1024 / 32)); |
270 | emsg); | 297 | if (mod == 0) |
271 | return; | 298 | mod = 1; |
272 | } | 299 | cbuf[pos] = (uint8_t) ((offset * (*publish_seed)) % mod); |
273 | i = 0; | ||
274 | while (i < sctx->total) | ||
275 | { | ||
276 | if (GNUNET_TESTING_daemon_get (sctx->group, i) == d) | ||
277 | break; | ||
278 | i++; | ||
279 | } | ||
280 | GNUNET_assert (i < sctx->total); | ||
281 | GNUNET_assert (sctx->have < sctx->total); | ||
282 | GNUNET_assert (sctx->daemons[i]->cfg == NULL); | ||
283 | sctx->daemons[i]->cfg = GNUNET_CONFIGURATION_dup (cfg); | ||
284 | sctx->daemons[i]->group = sctx->group; | ||
285 | sctx->daemons[i]->daemon = d; | ||
286 | sctx->daemons[i]->id = *id; | ||
287 | sctx->have++; | ||
288 | if (sctx->have == sctx->total) | ||
289 | { | ||
290 | GNUNET_SCHEDULER_add_continuation (sctx->cont, sctx->cont_cls, | ||
291 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | ||
292 | sctx->daemons[0]->gcfg = sctx->cfg; | ||
293 | GNUNET_SCHEDULER_cancel (sctx->timeout_task); | ||
294 | for (i = 0; i < sctx->total; i++) | ||
295 | { | ||
296 | sctx->daemons[i]->fs = | ||
297 | GNUNET_FS_start (sctx->daemons[i]->cfg, "<tester>", &progress_cb, | ||
298 | sctx->daemons[i], GNUNET_FS_FLAGS_NONE, | ||
299 | GNUNET_FS_OPTIONS_END); | ||
300 | } | ||
301 | GNUNET_free (sctx); | ||
302 | } | 300 | } |
301 | return max; | ||
303 | } | 302 | } |
304 | 303 | ||
305 | 304 | ||
306 | static void | 305 | /** |
307 | start_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 306 | * Connect adapter for publishing operation. |
307 | * | ||
308 | * @param cls the 'struct TestPublishOperation' | ||
309 | * @param cfg configuration of the peer to connect to; will be available until | ||
310 | * GNUNET_TESTBED_operation_done() is called on the operation returned | ||
311 | * from GNUNET_TESTBED_service_connect() | ||
312 | * @return service handle to return in 'op_result', NULL on error | ||
313 | */ | ||
314 | static void * | ||
315 | publish_connect_adapter (void *cls, | ||
316 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
308 | { | 317 | { |
309 | struct StartContext *sctx = cls; | 318 | struct TestPublishOperation *po = cls; |
310 | unsigned int i; | 319 | |
311 | 320 | return GNUNET_FS_start (cfg, | |
312 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 321 | "fs-test-publish", |
313 | "Timeout while trying to start daemons\n"); | 322 | &publish_progress_cb, po, |
314 | GNUNET_TESTING_daemons_stop (sctx->group, | 323 | GNUNET_FS_OPTIONS_END); |
315 | GNUNET_TIME_relative_multiply | ||
316 | (GNUNET_TIME_UNIT_SECONDS, 30), | ||
317 | &shutdown_callback, NULL); | ||
318 | for (i = 0; i < sctx->total; i++) | ||
319 | { | ||
320 | if (i < sctx->have) | ||
321 | GNUNET_CONFIGURATION_destroy (sctx->daemons[i]->cfg); | ||
322 | GNUNET_free (sctx->daemons[i]); | ||
323 | sctx->daemons[i] = NULL; | ||
324 | } | ||
325 | GNUNET_CONFIGURATION_destroy (sctx->cfg); | ||
326 | GNUNET_SCHEDULER_add_continuation (sctx->cont, sctx->cont_cls, | ||
327 | GNUNET_SCHEDULER_REASON_TIMEOUT); | ||
328 | GNUNET_free (sctx); | ||
329 | } | 324 | } |
330 | 325 | ||
331 | 326 | ||
332 | /** | 327 | /** |
333 | * Start daemons for testing. | 328 | * Adapter function called to destroy connection to file-sharing service. |
334 | * | 329 | * |
335 | * @param template_cfg_file configuration template to use | 330 | * @param cls the 'struct GNUNET_FS_Handle' |
336 | * @param timeout if this operation cannot be completed within the | 331 | * @param op_result unused (different for publish/download!) |
337 | * given period, call the continuation with an error code | ||
338 | * @param total number of daemons to start | ||
339 | * @param daemons array of 'total' entries to be initialized | ||
340 | * (array must already be allocated, will be filled) | ||
341 | * @param cont function to call when done | ||
342 | * @param cont_cls closure for cont | ||
343 | */ | 332 | */ |
344 | void | 333 | static void |
345 | GNUNET_FS_TEST_daemons_start (const char *template_cfg_file, | 334 | fs_disconnect_adapter (void *cls, |
346 | struct GNUNET_TIME_Relative timeout, | 335 | void *op_result) |
347 | unsigned int total, | ||
348 | struct GNUNET_FS_TestDaemon **daemons, | ||
349 | GNUNET_SCHEDULER_Task cont, void *cont_cls) | ||
350 | { | 336 | { |
351 | struct StartContext *sctx; | 337 | struct GNUNET_FS_Handle *fs = op_result; |
352 | unsigned int i; | ||
353 | |||
354 | GNUNET_assert (total > 0); | ||
355 | sctx = GNUNET_malloc (sizeof (struct StartContext)); | ||
356 | sctx->daemons = daemons; | ||
357 | sctx->total = total; | ||
358 | sctx->cont = cont; | ||
359 | sctx->cont_cls = cont_cls; | ||
360 | sctx->cfg = GNUNET_CONFIGURATION_create (); | ||
361 | if (GNUNET_OK != GNUNET_CONFIGURATION_load (sctx->cfg, template_cfg_file)) | ||
362 | { | ||
363 | GNUNET_break (0); | ||
364 | GNUNET_CONFIGURATION_destroy (sctx->cfg); | ||
365 | GNUNET_free (sctx); | ||
366 | GNUNET_SCHEDULER_add_continuation (cont, cont_cls, | ||
367 | GNUNET_SCHEDULER_REASON_TIMEOUT); | ||
368 | return; | ||
369 | } | ||
370 | for (i = 0; i < total; i++) | ||
371 | daemons[i] = GNUNET_malloc (sizeof (struct GNUNET_FS_TestDaemon)); | ||
372 | sctx->group = GNUNET_TESTING_daemons_start (sctx->cfg, total, total, /* Outstanding connections */ | ||
373 | total, /* Outstanding ssh connections */ | ||
374 | timeout, NULL, NULL, | ||
375 | ¬ify_running, sctx, NULL, NULL, | ||
376 | NULL); | ||
377 | sctx->timeout_task = | ||
378 | GNUNET_SCHEDULER_add_delayed (timeout, &start_timeout, sctx); | ||
379 | } | ||
380 | 338 | ||
381 | 339 | GNUNET_FS_stop (fs); | |
382 | struct GNUNET_FS_TEST_ConnectContext | 340 | } |
383 | { | ||
384 | GNUNET_SCHEDULER_Task cont; | ||
385 | void *cont_cls; | ||
386 | struct GNUNET_TESTING_ConnectContext *cc; | ||
387 | }; | ||
388 | 341 | ||
389 | 342 | ||
390 | /** | 343 | /** |
391 | * Prototype of a function that will be called whenever | 344 | * Callback to be called when testbed has connected to the fs service |
392 | * two daemons are connected by the testing library. | ||
393 | * | 345 | * |
394 | * @param cls closure | 346 | * @param cls the 'struct TestPublishOperation' |
395 | * @param first peer id for first daemon | 347 | * @param op the operation that has been finished |
396 | * @param second peer id for the second daemon | 348 | * @param ca_result the 'struct GNUNET_FS_Handle ' (NULL on error) |
397 | * @param distance distance between the connected peers | 349 | * @param emsg error message in case the operation has failed; will be NULL if |
398 | * @param first_cfg config for the first daemon | 350 | * operation has executed successfully. |
399 | * @param second_cfg config for the second daemon | ||
400 | * @param first_daemon handle for the first daemon | ||
401 | * @param second_daemon handle for the second daemon | ||
402 | * @param emsg error message (NULL on success) | ||
403 | */ | 351 | */ |
404 | static void | 352 | static void |
405 | notify_connection (void *cls, const struct GNUNET_PeerIdentity *first, | 353 | publish_fs_connect_complete_cb (void *cls, |
406 | const struct GNUNET_PeerIdentity *second, uint32_t distance, | 354 | struct GNUNET_TESTBED_Operation *op, |
407 | const struct GNUNET_CONFIGURATION_Handle *first_cfg, | 355 | void *ca_result, |
408 | const struct GNUNET_CONFIGURATION_Handle *second_cfg, | 356 | const char *emsg) |
409 | struct GNUNET_TESTING_Daemon *first_daemon, | ||
410 | struct GNUNET_TESTING_Daemon *second_daemon, | ||
411 | const char *emsg) | ||
412 | { | 357 | { |
413 | struct GNUNET_FS_TEST_ConnectContext *cc = cls; | 358 | struct TestPublishOperation *po = cls; |
359 | struct GNUNET_FS_FileInformation *fi; | ||
360 | struct GNUNET_DISK_FileHandle *fh; | ||
361 | char *em; | ||
362 | uint64_t off; | ||
363 | char buf[DBLOCK_SIZE]; | ||
364 | size_t bsize; | ||
365 | struct GNUNET_FS_BlockOptions bo; | ||
414 | 366 | ||
415 | cc->cc = NULL; | 367 | if (NULL == ca_result) |
416 | if (emsg != NULL) | 368 | { |
417 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to connect peers: %s\n", | 369 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to connect to FS for publishing: %s\n", emsg); |
418 | emsg); | 370 | po->publish_cont (po->publish_cont_cls, |
419 | GNUNET_SCHEDULER_add_continuation (cc->cont, cc->cont_cls, | 371 | NULL); |
420 | (emsg != | 372 | GNUNET_TESTBED_operation_done (po->fs_op); |
421 | NULL) ? GNUNET_SCHEDULER_REASON_TIMEOUT : | 373 | GNUNET_free (po); |
422 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | 374 | return; |
423 | GNUNET_free (cc); | 375 | } |
376 | po->fs = ca_result; | ||
377 | |||
378 | bo.expiration_time = GNUNET_TIME_relative_to_absolute (CONTENT_LIFETIME); | ||
379 | bo.anonymity_level = po->anonymity; | ||
380 | bo.content_priority = 42; | ||
381 | bo.replication_level = 1; | ||
382 | if (GNUNET_YES == po->do_index) | ||
383 | { | ||
384 | po->publish_tmp_file = GNUNET_DISK_mktemp ("fs-test-publish-index"); | ||
385 | GNUNET_assert (po->publish_tmp_file != NULL); | ||
386 | fh = GNUNET_DISK_file_open (po->publish_tmp_file, | ||
387 | GNUNET_DISK_OPEN_WRITE | | ||
388 | GNUNET_DISK_OPEN_CREATE, | ||
389 | GNUNET_DISK_PERM_USER_READ | | ||
390 | GNUNET_DISK_PERM_USER_WRITE); | ||
391 | GNUNET_assert (NULL != fh); | ||
392 | off = 0; | ||
393 | while (off < po->size) | ||
394 | { | ||
395 | bsize = GNUNET_MIN (sizeof (buf), po->size - off); | ||
396 | emsg = NULL; | ||
397 | GNUNET_assert (bsize == file_generator (&po->publish_seed, off, bsize, buf, &em)); | ||
398 | GNUNET_assert (em == NULL); | ||
399 | GNUNET_assert (bsize == GNUNET_DISK_file_write (fh, buf, bsize)); | ||
400 | off += bsize; | ||
401 | } | ||
402 | GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh)); | ||
403 | fi = GNUNET_FS_file_information_create_from_file (po->fs, po, | ||
404 | po->publish_tmp_file, | ||
405 | NULL, NULL, po->do_index, | ||
406 | &bo); | ||
407 | } | ||
408 | else | ||
409 | { | ||
410 | fi = GNUNET_FS_file_information_create_from_reader (po->fs, po, | ||
411 | po->size, | ||
412 | &file_generator, &po->publish_seed, | ||
413 | NULL, NULL, | ||
414 | po->do_index, &bo); | ||
415 | } | ||
416 | po->publish_context = | ||
417 | GNUNET_FS_publish_start (po->fs, fi, NULL, NULL, NULL, | ||
418 | GNUNET_FS_PUBLISH_OPTION_NONE); | ||
424 | } | 419 | } |
425 | 420 | ||
426 | 421 | ||
427 | /** | 422 | /** |
428 | * Connect two daemons for testing. | 423 | * Publish a file at the given peer. |
429 | * | 424 | * |
430 | * @param daemon1 first daemon to connect | 425 | * @param peer where to publish |
431 | * @param daemon2 second first daemon to connect | ||
432 | * @param timeout if this operation cannot be completed within the | 426 | * @param timeout if this operation cannot be completed within the |
433 | * given period, call the continuation with an error code | 427 | * given period, call the continuation with an error code |
428 | * @param anonymity option for publication | ||
429 | * @param do_index GNUNET_YES for index, GNUNET_NO for insertion, | ||
430 | * GNUNET_SYSERR for simulation | ||
431 | * @param size size of the file to publish | ||
432 | * @param seed seed to use for file generation | ||
433 | * @param verbose how verbose to be in reporting | ||
434 | * @param cont function to call when done | 434 | * @param cont function to call when done |
435 | * @param cont_cls closure for cont | 435 | * @param cont_cls closure for cont |
436 | */ | 436 | */ |
437 | struct GNUNET_FS_TEST_ConnectContext * | 437 | void |
438 | GNUNET_FS_TEST_daemons_connect (struct GNUNET_FS_TestDaemon *daemon1, | 438 | GNUNET_FS_TEST_publish (struct GNUNET_TESTBED_Peer *peer, |
439 | struct GNUNET_FS_TestDaemon *daemon2, | 439 | struct GNUNET_TIME_Relative timeout, uint32_t anonymity, |
440 | struct GNUNET_TIME_Relative timeout, | 440 | int do_index, uint64_t size, uint32_t seed, |
441 | GNUNET_SCHEDULER_Task cont, void *cont_cls) | 441 | unsigned int verbose, |
442 | GNUNET_FS_TEST_UriContinuation cont, void *cont_cls) | ||
442 | { | 443 | { |
443 | struct GNUNET_FS_TEST_ConnectContext *ncc; | 444 | struct TestPublishOperation *po; |
444 | 445 | ||
445 | ncc = GNUNET_malloc (sizeof (struct GNUNET_FS_TEST_ConnectContext)); | 446 | po = GNUNET_malloc (sizeof (struct TestPublishOperation)); |
446 | ncc->cont = cont; | 447 | po->publish_cont = cont; |
447 | ncc->cont_cls = cont_cls; | 448 | po->publish_cont_cls = cont_cls; |
448 | ncc->cc = | 449 | po->publish_seed = seed; |
449 | GNUNET_TESTING_daemons_connect (daemon1->daemon, daemon2->daemon, timeout, | 450 | po->anonymity = anonymity; |
450 | CONNECT_ATTEMPTS, GNUNET_YES, | 451 | po->size = size; |
451 | ¬ify_connection, ncc); | 452 | po->verbose = verbose; |
452 | return ncc; | 453 | po->do_index = do_index; |
454 | po->fs_op = GNUNET_TESTBED_service_connect (po, | ||
455 | peer, | ||
456 | "fs", | ||
457 | &publish_fs_connect_complete_cb, | ||
458 | po, | ||
459 | &publish_connect_adapter, | ||
460 | &fs_disconnect_adapter, | ||
461 | po); | ||
462 | po->publish_timeout_task = | ||
463 | GNUNET_SCHEDULER_add_delayed (timeout, &publish_timeout, po); | ||
453 | } | 464 | } |
454 | 465 | ||
455 | 466 | ||
456 | /** | 467 | /* ************************** download ************************ */ |
457 | * Cancel connect operation. | ||
458 | * | ||
459 | * @param cc operation to cancel | ||
460 | */ | ||
461 | void | ||
462 | GNUNET_FS_TEST_daemons_connect_cancel (struct GNUNET_FS_TEST_ConnectContext *cc) | ||
463 | { | ||
464 | GNUNET_TESTING_daemons_connect_cancel (cc->cc); | ||
465 | GNUNET_free (cc); | ||
466 | } | ||
467 | 468 | ||
468 | 469 | ||
469 | /** | 470 | /** |
470 | * Obtain peer configuration used for testing. | 471 | * Task scheduled to run when download operation times out. |
471 | * | 472 | * |
472 | * @param daemons array with the daemons | 473 | * @param cls the download operation context |
473 | * @param off which configuration to get | 474 | * @param tc scheduler context (unused) |
474 | * @return peer configuration | ||
475 | */ | 475 | */ |
476 | const struct GNUNET_CONFIGURATION_Handle * | 476 | static void |
477 | GNUNET_FS_TEST_get_configuration (struct GNUNET_FS_TestDaemon **daemons, | 477 | download_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
478 | unsigned int off) | ||
479 | { | 478 | { |
480 | return daemons[off]->cfg; | 479 | struct TestDownloadOperation *dop = cls; |
481 | } | ||
482 | 480 | ||
483 | /** | 481 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
484 | * Obtain peer group used for testing. | 482 | "Timeout while trying to download file\n"); |
485 | * | 483 | dop->download_timeout_task = GNUNET_SCHEDULER_NO_TASK; |
486 | * @param daemons array with the daemons (must contain at least one) | 484 | GNUNET_FS_download_stop (dop->download_context, GNUNET_YES); |
487 | * @return peer group | 485 | GNUNET_SCHEDULER_add_continuation (dop->download_cont, |
488 | */ | 486 | dop->download_cont_cls, |
489 | struct GNUNET_TESTING_PeerGroup * | 487 | GNUNET_SCHEDULER_REASON_TIMEOUT); |
490 | GNUNET_FS_TEST_get_group (struct GNUNET_FS_TestDaemon **daemons) | 488 | if (NULL == dop->fs) |
491 | { | 489 | GNUNET_TESTBED_operation_cancel (dop->fs_op); |
492 | return daemons[0]->group; | 490 | else |
491 | GNUNET_TESTBED_operation_done (dop->fs_op); | ||
492 | GNUNET_FS_uri_destroy (dop->uri); | ||
493 | GNUNET_free (dop); | ||
493 | } | 494 | } |
494 | 495 | ||
495 | 496 | ||
496 | /** | 497 | /** |
497 | * Stop daemons used for testing. | 498 | * Task scheduled to report on the completion of our download operation. |
498 | * | 499 | * |
499 | * @param total number of daemons to stop | 500 | * @param cls the download operation context |
500 | * @param daemons array with the daemons (values will be clobbered) | 501 | * @param tc scheduler context (unused) |
501 | */ | 502 | */ |
502 | void | ||
503 | GNUNET_FS_TEST_daemons_stop (unsigned int total, | ||
504 | struct GNUNET_FS_TestDaemon **daemons) | ||
505 | { | ||
506 | unsigned int i; | ||
507 | struct GNUNET_TESTING_PeerGroup *pg; | ||
508 | struct GNUNET_CONFIGURATION_Handle *gcfg; | ||
509 | struct GNUNET_FS_TestDaemon *daemon; | ||
510 | |||
511 | GNUNET_assert (total > 0); | ||
512 | GNUNET_assert (daemons[0] != NULL); | ||
513 | pg = daemons[0]->group; | ||
514 | gcfg = daemons[0]->gcfg; | ||
515 | for (i = 0; i < total; i++) | ||
516 | { | ||
517 | daemon = daemons[i]; | ||
518 | if (daemon->download_timeout_task != GNUNET_SCHEDULER_NO_TASK) | ||
519 | { | ||
520 | GNUNET_SCHEDULER_cancel (daemon->download_timeout_task); | ||
521 | daemon->download_timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
522 | } | ||
523 | if (daemon->publish_timeout_task != GNUNET_SCHEDULER_NO_TASK) | ||
524 | { | ||
525 | GNUNET_SCHEDULER_cancel (daemon->publish_timeout_task); | ||
526 | daemon->publish_timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
527 | } | ||
528 | if (NULL != daemon->download_context) | ||
529 | { | ||
530 | GNUNET_FS_download_stop (daemon->download_context, GNUNET_YES); | ||
531 | daemon->download_context = NULL; | ||
532 | } | ||
533 | if (daemon->fs != NULL) | ||
534 | GNUNET_FS_stop (daemon->fs); | ||
535 | if (daemon->cfg != NULL) | ||
536 | GNUNET_CONFIGURATION_destroy (daemon->cfg); | ||
537 | if (NULL != daemon->publish_tmp_file) | ||
538 | { | ||
539 | GNUNET_break (GNUNET_OK == | ||
540 | GNUNET_DISK_directory_remove (daemon->publish_tmp_file)); | ||
541 | GNUNET_free (daemon->publish_tmp_file); | ||
542 | daemon->publish_tmp_file = NULL; | ||
543 | } | ||
544 | GNUNET_free (daemon); | ||
545 | daemons[i] = NULL; | ||
546 | } | ||
547 | GNUNET_TESTING_daemons_stop (pg, | ||
548 | GNUNET_TIME_relative_multiply | ||
549 | (GNUNET_TIME_UNIT_SECONDS, 30), | ||
550 | &shutdown_callback, gcfg); | ||
551 | } | ||
552 | |||
553 | |||
554 | static void | 503 | static void |
555 | publish_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 504 | report_success (void *cls, |
505 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
556 | { | 506 | { |
557 | struct GNUNET_FS_TestDaemon *daemon = cls; | 507 | struct TestDownloadOperation *dop = cls; |
558 | GNUNET_FS_TEST_UriContinuation cont; | ||
559 | 508 | ||
560 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 509 | GNUNET_FS_download_stop (dop->download_context, GNUNET_YES); |
561 | "Timeout while trying to publish data\n"); | 510 | GNUNET_SCHEDULER_add_continuation (dop->download_cont, |
562 | cont = daemon->publish_cont; | 511 | dop->download_cont_cls, |
563 | daemon->publish_timeout_task = GNUNET_SCHEDULER_NO_TASK; | 512 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); |
564 | daemon->publish_cont = NULL; | 513 | GNUNET_TESTBED_operation_done (dop->fs_op); |
565 | GNUNET_FS_publish_stop (daemon->publish_context); | 514 | GNUNET_FS_uri_destroy (dop->uri); |
566 | daemon->publish_context = NULL; | 515 | GNUNET_free (dop); |
567 | cont (daemon->publish_cont_cls, NULL); | ||
568 | } | 516 | } |
569 | 517 | ||
570 | 518 | ||
571 | static size_t | 519 | /** |
572 | file_generator (void *cls, uint64_t offset, size_t max, void *buf, char **emsg) | 520 | * Progress callback for file-sharing events while downloading. |
521 | * | ||
522 | * @param cls the download operation context | ||
523 | * @param info information about the event | ||
524 | */ | ||
525 | static void * | ||
526 | download_progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) | ||
573 | { | 527 | { |
574 | struct GNUNET_FS_TestDaemon *daemon = cls; | 528 | struct TestDownloadOperation *dop = cls; |
575 | uint64_t pos; | ||
576 | uint8_t *cbuf = buf; | ||
577 | int mod; | ||
578 | 529 | ||
579 | if (emsg != NULL) | 530 | switch (info->status) |
580 | *emsg = NULL; | ||
581 | if (buf == NULL) | ||
582 | return 0; | ||
583 | for (pos = 0; pos < 8; pos++) | ||
584 | cbuf[pos] = (uint8_t) (offset >> pos * 8); | ||
585 | for (pos = 8; pos < max; pos++) | ||
586 | { | 531 | { |
587 | mod = (255 - (offset / 1024 / 32)); | 532 | case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS: |
588 | if (mod == 0) | 533 | if (dop->verbose) |
589 | mod = 1; | 534 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Download at %llu/%llu bytes\n", |
590 | cbuf[pos] = (uint8_t) ((offset * daemon->publish_seed) % mod); | 535 | (unsigned long long) info->value.download.completed, |
536 | (unsigned long long) info->value.download.size); | ||
537 | break; | ||
538 | case GNUNET_FS_STATUS_DOWNLOAD_COMPLETED: | ||
539 | GNUNET_SCHEDULER_cancel (dop->download_timeout_task); | ||
540 | dop->download_timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
541 | GNUNET_SCHEDULER_add_continuation (&report_success, dop, | ||
542 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | ||
543 | break; | ||
544 | case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE: | ||
545 | case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE: | ||
546 | break; | ||
547 | /* FIXME: monitor data correctness during download progress */ | ||
548 | /* FIXME: do performance reports given sufficient verbosity */ | ||
549 | /* FIXME: advance timeout task to "immediate" on error */ | ||
550 | default: | ||
551 | break; | ||
591 | } | 552 | } |
592 | return max; | 553 | return NULL; |
593 | } | 554 | } |
594 | 555 | ||
595 | 556 | ||
596 | |||
597 | /** | 557 | /** |
598 | * Publish a file at the given daemon. | 558 | * Connect adapter for download operation. |
599 | * | 559 | * |
600 | * @param daemon where to publish | 560 | * @param cls the 'struct TestDownloadOperation' |
601 | * @param timeout if this operation cannot be completed within the | 561 | * @param cfg configuration of the peer to connect to; will be available until |
602 | * given period, call the continuation with an error code | 562 | * GNUNET_TESTBED_operation_done() is called on the operation returned |
603 | * @param anonymity option for publication | 563 | * from GNUNET_TESTBED_service_connect() |
604 | * @param do_index GNUNET_YES for index, GNUNET_NO for insertion, | 564 | * @return service handle to return in 'op_result', NULL on error |
605 | * GNUNET_SYSERR for simulation | ||
606 | * @param size size of the file to publish | ||
607 | * @param seed seed to use for file generation | ||
608 | * @param verbose how verbose to be in reporting | ||
609 | * @param cont function to call when done | ||
610 | * @param cont_cls closure for cont | ||
611 | */ | 565 | */ |
612 | void | 566 | static void * |
613 | GNUNET_FS_TEST_publish (struct GNUNET_FS_TestDaemon *daemon, | 567 | download_connect_adapter (void *cls, |
614 | struct GNUNET_TIME_Relative timeout, uint32_t anonymity, | 568 | const struct GNUNET_CONFIGURATION_Handle *cfg) |
615 | int do_index, uint64_t size, uint32_t seed, | ||
616 | unsigned int verbose, | ||
617 | GNUNET_FS_TEST_UriContinuation cont, void *cont_cls) | ||
618 | { | 569 | { |
619 | struct GNUNET_FS_FileInformation *fi; | 570 | struct TestPublishOperation *po = cls; |
620 | struct GNUNET_DISK_FileHandle *fh; | 571 | |
621 | char *emsg; | 572 | return GNUNET_FS_start (cfg, |
622 | uint64_t off; | 573 | "fs-test-download", |
623 | char buf[DBLOCK_SIZE]; | 574 | &download_progress_cb, po, |
624 | size_t bsize; | 575 | GNUNET_FS_OPTIONS_END); |
625 | struct GNUNET_FS_BlockOptions bo; | ||
626 | |||
627 | GNUNET_assert (daemon->publish_cont == NULL); | ||
628 | daemon->publish_cont = cont; | ||
629 | daemon->publish_cont_cls = cont_cls; | ||
630 | daemon->publish_seed = seed; | ||
631 | daemon->verbose = verbose; | ||
632 | bo.expiration_time = GNUNET_TIME_relative_to_absolute (CONTENT_LIFETIME); | ||
633 | bo.anonymity_level = anonymity; | ||
634 | bo.content_priority = 42; | ||
635 | bo.replication_level = 1; | ||
636 | if (GNUNET_YES == do_index) | ||
637 | { | ||
638 | GNUNET_assert (daemon->publish_tmp_file == NULL); | ||
639 | daemon->publish_tmp_file = GNUNET_DISK_mktemp ("fs-test-publish-index"); | ||
640 | GNUNET_assert (daemon->publish_tmp_file != NULL); | ||
641 | fh = GNUNET_DISK_file_open (daemon->publish_tmp_file, | ||
642 | GNUNET_DISK_OPEN_WRITE | | ||
643 | GNUNET_DISK_OPEN_CREATE, | ||
644 | GNUNET_DISK_PERM_USER_READ | | ||
645 | GNUNET_DISK_PERM_USER_WRITE); | ||
646 | GNUNET_assert (NULL != fh); | ||
647 | off = 0; | ||
648 | while (off < size) | ||
649 | { | ||
650 | bsize = GNUNET_MIN (sizeof (buf), size - off); | ||
651 | emsg = NULL; | ||
652 | GNUNET_assert (bsize == file_generator (daemon, off, bsize, buf, &emsg)); | ||
653 | GNUNET_assert (emsg == NULL); | ||
654 | GNUNET_assert (bsize == GNUNET_DISK_file_write (fh, buf, bsize)); | ||
655 | off += bsize; | ||
656 | } | ||
657 | GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh)); | ||
658 | fi = GNUNET_FS_file_information_create_from_file (daemon->fs, daemon, | ||
659 | daemon->publish_tmp_file, | ||
660 | NULL, NULL, do_index, | ||
661 | &bo); | ||
662 | } | ||
663 | else | ||
664 | { | ||
665 | fi = GNUNET_FS_file_information_create_from_reader (daemon->fs, daemon, | ||
666 | size, &file_generator, | ||
667 | daemon, NULL, NULL, | ||
668 | do_index, &bo); | ||
669 | } | ||
670 | daemon->publish_context = | ||
671 | GNUNET_FS_publish_start (daemon->fs, fi, NULL, NULL, NULL, | ||
672 | GNUNET_FS_PUBLISH_OPTION_NONE); | ||
673 | daemon->publish_timeout_task = | ||
674 | GNUNET_SCHEDULER_add_delayed (timeout, &publish_timeout, daemon); | ||
675 | } | 576 | } |
676 | 577 | ||
677 | 578 | ||
579 | /** | ||
580 | * Callback to be called when testbed has connected to the fs service | ||
581 | * | ||
582 | * @param cls the 'struct TestPublishOperation' | ||
583 | * @param op the operation that has been finished | ||
584 | * @param ca_result the 'struct GNUNET_FS_Handle ' (NULL on error) | ||
585 | * @param emsg error message in case the operation has failed; will be NULL if | ||
586 | * operation has executed successfully. | ||
587 | */ | ||
678 | static void | 588 | static void |
679 | download_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 589 | download_fs_connect_complete_cb (void *cls, |
590 | struct GNUNET_TESTBED_Operation *op, | ||
591 | void *ca_result, | ||
592 | const char *emsg) | ||
680 | { | 593 | { |
681 | struct GNUNET_FS_TestDaemon *daemon = cls; | 594 | struct TestDownloadOperation *dop = cls; |
682 | 595 | ||
683 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 596 | dop->download_context = |
684 | "Timeout while trying to download file\n"); | 597 | GNUNET_FS_download_start (dop->fs, dop->uri, NULL, NULL, NULL, 0, dop->size, |
685 | daemon->download_timeout_task = GNUNET_SCHEDULER_NO_TASK; | 598 | dop->anonymity, GNUNET_FS_DOWNLOAD_OPTION_NONE, |
686 | GNUNET_FS_download_stop (daemon->download_context, GNUNET_YES); | 599 | NULL, NULL); |
687 | daemon->download_context = NULL; | ||
688 | GNUNET_SCHEDULER_add_continuation (daemon->download_cont, | ||
689 | daemon->download_cont_cls, | ||
690 | GNUNET_SCHEDULER_REASON_TIMEOUT); | ||
691 | daemon->download_cont = NULL; | ||
692 | } | 600 | } |
693 | 601 | ||
694 | 602 | ||
695 | /** | 603 | /** |
696 | * Perform test download. | 604 | * Perform test download. |
697 | * | 605 | * |
698 | * @param daemon which peer to download from | 606 | * @param peer which peer to download from |
699 | * @param timeout if this operation cannot be completed within the | 607 | * @param timeout if this operation cannot be completed within the |
700 | * given period, call the continuation with an error code | 608 | * given period, call the continuation with an error code |
701 | * @param anonymity option for download | 609 | * @param anonymity option for download |
@@ -706,26 +614,34 @@ download_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
706 | * @param cont_cls closure for cont | 614 | * @param cont_cls closure for cont |
707 | */ | 615 | */ |
708 | void | 616 | void |
709 | GNUNET_FS_TEST_download (struct GNUNET_FS_TestDaemon *daemon, | 617 | GNUNET_FS_TEST_download (struct GNUNET_TESTBED_Peer *peer, |
710 | struct GNUNET_TIME_Relative timeout, | 618 | struct GNUNET_TIME_Relative timeout, |
711 | uint32_t anonymity, uint32_t seed, | 619 | uint32_t anonymity, uint32_t seed, |
712 | const struct GNUNET_FS_Uri *uri, unsigned int verbose, | 620 | const struct GNUNET_FS_Uri *uri, unsigned int verbose, |
713 | GNUNET_SCHEDULER_Task cont, void *cont_cls) | 621 | GNUNET_SCHEDULER_Task cont, void *cont_cls) |
714 | { | 622 | { |
715 | uint64_t size; | 623 | struct TestDownloadOperation *dop; |
716 | 624 | ||
717 | GNUNET_assert (daemon->download_cont == NULL); | 625 | dop = GNUNET_malloc (sizeof (struct TestDownloadOperation)); |
718 | size = GNUNET_FS_uri_chk_get_file_size (uri); | 626 | dop->uri = GNUNET_FS_uri_dup (uri); |
719 | daemon->verbose = verbose; | 627 | dop->size = GNUNET_FS_uri_chk_get_file_size (uri); |
720 | daemon->download_cont = cont; | 628 | dop->verbose = verbose; |
721 | daemon->download_cont_cls = cont_cls; | 629 | dop->anonymity = anonymity; |
722 | daemon->download_seed = seed; | 630 | dop->download_cont = cont; |
723 | daemon->download_context = | 631 | dop->download_cont_cls = cont_cls; |
724 | GNUNET_FS_download_start (daemon->fs, uri, NULL, NULL, NULL, 0, size, | 632 | dop->download_seed = seed; |
725 | anonymity, GNUNET_FS_DOWNLOAD_OPTION_NONE, NULL, | 633 | |
726 | NULL); | 634 | dop->fs_op = GNUNET_TESTBED_service_connect (dop, |
727 | daemon->download_timeout_task = | 635 | peer, |
728 | GNUNET_SCHEDULER_add_delayed (timeout, &download_timeout, daemon); | 636 | "fs", |
637 | &download_fs_connect_complete_cb, | ||
638 | dop, | ||
639 | &download_connect_adapter, | ||
640 | &fs_disconnect_adapter, | ||
641 | dop); | ||
642 | dop->download_timeout_task = | ||
643 | GNUNET_SCHEDULER_add_delayed (timeout, &download_timeout, dop); | ||
729 | } | 644 | } |
730 | 645 | ||
731 | /* end of test_fs_lib.c */ | 646 | |
647 | /* end of fs_test_lib.c */ | ||