aboutsummaryrefslogtreecommitdiff
path: root/src/fs/fs_test_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/fs_test_lib.c')
-rw-r--r--src/fs/fs_test_lib.c630
1 files changed, 0 insertions, 630 deletions
diff --git a/src/fs/fs_test_lib.c b/src/fs/fs_test_lib.c
deleted file mode 100644
index f80a2859c..000000000
--- a/src/fs/fs_test_lib.c
+++ /dev/null
@@ -1,630 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2010, 2011, 2012 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 fs/fs_test_lib.c
23 * @brief library routines for testing FS publishing and downloading;
24 * this code is limited to flat files
25 * and no keywords (those functions can be tested with
26 * single-peer setups; this is for testing routing).
27 * @author Christian Grothoff
28 */
29#include "platform.h"
30#include "fs_api.h"
31#include "fs_test_lib.h"
32
33
34#define CONTENT_LIFETIME GNUNET_TIME_UNIT_HOURS
35
36
37/**
38 * Handle for a publishing operation started for testing FS.
39 */
40struct TestPublishOperation
41{
42 /**
43 * Handle for the operation to connect to the peer's 'fs' service.
44 */
45 struct GNUNET_TESTBED_Operation *fs_op;
46
47 /**
48 * Handle to the file sharing context using this daemon.
49 */
50 struct GNUNET_FS_Handle *fs;
51
52 /**
53 * Function to call when upload is done.
54 */
55 GNUNET_FS_TEST_UriContinuation publish_cont;
56
57 /**
58 * Closure for publish_cont.
59 */
60 void *publish_cont_cls;
61
62 /**
63 * Task to abort publishing (timeout).
64 */
65 struct GNUNET_SCHEDULER_Task *publish_timeout_task;
66
67 /**
68 * Seed for file generation.
69 */
70 uint32_t publish_seed;
71
72 /**
73 * Context for current publishing operation.
74 */
75 struct GNUNET_FS_PublishContext *publish_context;
76
77 /**
78 * Result URI.
79 */
80 struct GNUNET_FS_Uri *publish_uri;
81
82 /**
83 * Name of the temporary file used, or NULL for none.
84 */
85 char *publish_tmp_file;
86
87 /**
88 * Size of the file.
89 */
90 uint64_t size;
91
92 /**
93 * Anonymity level used.
94 */
95 uint32_t anonymity;
96
97 /**
98 * Verbosity level of the current operation.
99 */
100 unsigned int verbose;
101
102 /**
103 * Are we testing indexing? (YES: index, NO: insert, SYSERR: simulate)
104 */
105 int do_index;
106};
107
108
109/**
110 * Handle for a download operation started for testing FS.
111 */
112struct TestDownloadOperation
113{
114 /**
115 * Handle for the operation to connect to the peer's 'fs' service.
116 */
117 struct GNUNET_TESTBED_Operation *fs_op;
118
119 /**
120 * Handle to the file sharing context using this daemon.
121 */
122 struct GNUNET_FS_Handle *fs;
123
124 /**
125 * Handle to the daemon via testing.
126 */
127 struct GNUNET_TESTING_Daemon *daemon;
128
129 /**
130 * Function to call when download is done.
131 */
132 GNUNET_SCHEDULER_TaskCallback download_cont;
133
134 /**
135 * Closure for download_cont.
136 */
137 void *download_cont_cls;
138
139 /**
140 * URI to download.
141 */
142 struct GNUNET_FS_Uri *uri;
143
144 /**
145 * Task to abort downloading (timeout).
146 */
147 struct GNUNET_SCHEDULER_Task *download_timeout_task;
148
149 /**
150 * Context for current download operation.
151 */
152 struct GNUNET_FS_DownloadContext *download_context;
153
154 /**
155 * Size of the file.
156 */
157 uint64_t size;
158
159 /**
160 * Anonymity level used.
161 */
162 uint32_t anonymity;
163
164 /**
165 * Seed for download verification.
166 */
167 uint32_t download_seed;
168
169 /**
170 * Verbosity level of the current operation.
171 */
172 unsigned int verbose;
173};
174
175
176/**
177 * Task scheduled to report on the completion of our publish operation.
178 *
179 * @param cls the publish operation context
180 */
181static void
182report_uri (void *cls)
183{
184 struct TestPublishOperation *po = cls;
185
186 GNUNET_FS_publish_stop (po->publish_context);
187 GNUNET_TESTBED_operation_done (po->fs_op);
188 po->publish_cont (po->publish_cont_cls,
189 po->publish_uri,
190 (GNUNET_YES == po->do_index)
191 ? po->publish_tmp_file
192 : NULL);
193 GNUNET_FS_uri_destroy (po->publish_uri);
194 if ((GNUNET_YES != po->do_index) &&
195 (NULL != po->publish_tmp_file))
196 (void) GNUNET_DISK_directory_remove (po->publish_tmp_file);
197 GNUNET_free (po->publish_tmp_file);
198 GNUNET_free (po);
199}
200
201
202/**
203 * Task scheduled to run when publish operation times out.
204 *
205 * @param cls the publish operation context
206 */
207static void
208publish_timeout (void *cls)
209{
210 struct TestPublishOperation *po = cls;
211
212 po->publish_timeout_task = NULL;
213 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
214 "Timeout while trying to publish data\n");
215 GNUNET_TESTBED_operation_done (po->fs_op);
216 GNUNET_FS_publish_stop (po->publish_context);
217 po->publish_cont (po->publish_cont_cls, NULL, NULL);
218 (void) GNUNET_DISK_directory_remove (po->publish_tmp_file);
219 GNUNET_free (po->publish_tmp_file);
220 GNUNET_free (po);
221}
222
223
224/**
225 * Progress callback for file-sharing events while publishing.
226 *
227 * @param cls the publish operation context
228 * @param info information about the event
229 */
230static void *
231publish_progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info)
232{
233 struct TestPublishOperation *po = cls;
234
235 switch (info->status)
236 {
237 case GNUNET_FS_STATUS_PUBLISH_COMPLETED:
238 GNUNET_SCHEDULER_cancel (po->publish_timeout_task);
239 po->publish_timeout_task = NULL;
240 po->publish_uri =
241 GNUNET_FS_uri_dup (info->value.publish.specifics.completed.chk_uri);
242 GNUNET_SCHEDULER_add_now (&report_uri,
243 po);
244 break;
245
246 case GNUNET_FS_STATUS_PUBLISH_PROGRESS:
247 if (po->verbose)
248 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Publishing at %llu/%llu bytes\n",
249 (unsigned long long) info->value.publish.completed,
250 (unsigned long long) info->value.publish.size);
251 break;
252
253 case GNUNET_FS_STATUS_PUBLISH_PROGRESS_DIRECTORY:
254 break;
255
256 case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS:
257 if (po->verbose)
258 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Download at %llu/%llu bytes\n",
259 (unsigned long long) info->value.download.completed,
260 (unsigned long long) info->value.download.size);
261 break;
262
263 default:
264 break;
265 }
266 return NULL;
267}
268
269
270/**
271 * Generate test data for publishing test.
272 *
273 * @param cls pointer to uint32_t with publishing seed
274 * @param offset offset to generate data for
275 * @param max maximum number of bytes to generate
276 * @param buf where to write generated data
277 * @param emsg where to store error message (unused)
278 * @return number of bytes written to buf
279 */
280static size_t
281file_generator (void *cls,
282 uint64_t offset,
283 size_t max,
284 void *buf,
285 char **emsg)
286{
287 uint32_t *publish_seed = cls;
288 uint64_t pos;
289 uint8_t *cbuf = buf;
290 int mod;
291
292 if (emsg != NULL)
293 *emsg = NULL;
294 if (buf == NULL)
295 return 0;
296 for (pos = 0; pos < 8; pos++)
297 cbuf[pos] = (uint8_t) (offset >> pos * 8);
298 for (pos = 8; pos < max; pos++)
299 {
300 mod = (255 - (offset / 1024 / 32));
301 if (mod == 0)
302 mod = 1;
303 cbuf[pos] = (uint8_t) ((offset * (*publish_seed)) % mod);
304 }
305 return max;
306}
307
308
309/**
310 * Connect adapter for publishing operation.
311 *
312 * @param cls the 'struct TestPublishOperation'
313 * @param cfg configuration of the peer to connect to; will be available until
314 * GNUNET_TESTBED_operation_done() is called on the operation returned
315 * from GNUNET_TESTBED_service_connect()
316 * @return service handle to return in 'op_result', NULL on error
317 */
318static void *
319publish_connect_adapter (void *cls,
320 const struct GNUNET_CONFIGURATION_Handle *cfg)
321{
322 struct TestPublishOperation *po = cls;
323
324 return GNUNET_FS_start (cfg,
325 "fs-test-publish",
326 &publish_progress_cb, po,
327 GNUNET_FS_FLAGS_NONE,
328 GNUNET_FS_OPTIONS_END);
329}
330
331
332/**
333 * Adapter function called to destroy connection to file-sharing service.
334 *
335 * @param cls the 'struct GNUNET_FS_Handle'
336 * @param op_result unused (different for publish/download!)
337 */
338static void
339fs_disconnect_adapter (void *cls,
340 void *op_result)
341{
342 struct GNUNET_FS_Handle *fs = op_result;
343
344 GNUNET_FS_stop (fs);
345}
346
347
348/**
349 * Callback to be called when testbed has connected to the fs service
350 *
351 * @param cls the 'struct TestPublishOperation'
352 * @param op the operation that has been finished
353 * @param ca_result the 'struct GNUNET_FS_Handle ' (NULL on error)
354 * @param emsg error message in case the operation has failed; will be NULL if
355 * operation has executed successfully.
356 */
357static void
358publish_fs_connect_complete_cb (void *cls,
359 struct GNUNET_TESTBED_Operation *op,
360 void *ca_result,
361 const char *emsg)
362{
363 struct TestPublishOperation *po = cls;
364 struct GNUNET_FS_FileInformation *fi;
365 struct GNUNET_DISK_FileHandle *fh;
366 char *em;
367 uint64_t off;
368 char buf[DBLOCK_SIZE];
369 size_t bsize;
370 struct GNUNET_FS_BlockOptions bo;
371
372 if (NULL == ca_result)
373 {
374 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
375 "Failed to connect to FS for publishing: %s\n", emsg);
376 po->publish_cont (po->publish_cont_cls,
377 NULL, NULL);
378 GNUNET_TESTBED_operation_done (po->fs_op);
379 GNUNET_free (po);
380 return;
381 }
382 po->fs = ca_result;
383
384 bo.expiration_time = GNUNET_TIME_relative_to_absolute (CONTENT_LIFETIME);
385 bo.anonymity_level = po->anonymity;
386 bo.content_priority = 42;
387 bo.replication_level = 1;
388 if (GNUNET_YES == po->do_index)
389 {
390 po->publish_tmp_file = GNUNET_DISK_mktemp ("fs-test-publish-index");
391 GNUNET_assert (po->publish_tmp_file != NULL);
392 fh = GNUNET_DISK_file_open (po->publish_tmp_file,
393 GNUNET_DISK_OPEN_WRITE
394 | GNUNET_DISK_OPEN_CREATE,
395 GNUNET_DISK_PERM_USER_READ
396 | GNUNET_DISK_PERM_USER_WRITE);
397 GNUNET_assert (NULL != fh);
398 off = 0;
399 while (off < po->size)
400 {
401 bsize = GNUNET_MIN (sizeof(buf), po->size - off);
402 emsg = NULL;
403 GNUNET_assert (bsize == file_generator (&po->publish_seed, off, bsize,
404 buf, &em));
405 GNUNET_assert (em == NULL);
406 GNUNET_assert (bsize == GNUNET_DISK_file_write (fh, buf, bsize));
407 off += bsize;
408 }
409 GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh));
410 fi = GNUNET_FS_file_information_create_from_file (po->fs, po,
411 po->publish_tmp_file,
412 NULL, NULL, po->do_index,
413 &bo);
414 GNUNET_assert (NULL != fi);
415 }
416 else
417 {
418 fi = GNUNET_FS_file_information_create_from_reader (po->fs, po,
419 po->size,
420 &file_generator,
421 &po->publish_seed,
422 NULL, NULL,
423 po->do_index, &bo);
424 GNUNET_assert (NULL != fi);
425 }
426 po->publish_context =
427 GNUNET_FS_publish_start (po->fs, fi, NULL, NULL, NULL,
428 GNUNET_FS_PUBLISH_OPTION_NONE);
429}
430
431
432void
433GNUNET_FS_TEST_publish (struct GNUNET_TESTBED_Peer *peer,
434 struct GNUNET_TIME_Relative timeout, uint32_t anonymity,
435 int do_index, uint64_t size, uint32_t seed,
436 unsigned int verbose,
437 GNUNET_FS_TEST_UriContinuation cont, void *cont_cls)
438{
439 struct TestPublishOperation *po;
440
441 po = GNUNET_new (struct TestPublishOperation);
442 po->publish_cont = cont;
443 po->publish_cont_cls = cont_cls;
444 po->publish_seed = seed;
445 po->anonymity = anonymity;
446 po->size = size;
447 po->verbose = verbose;
448 po->do_index = do_index;
449 po->fs_op = GNUNET_TESTBED_service_connect (po,
450 peer,
451 "fs",
452 &publish_fs_connect_complete_cb,
453 po,
454 &publish_connect_adapter,
455 &fs_disconnect_adapter,
456 po);
457 po->publish_timeout_task =
458 GNUNET_SCHEDULER_add_delayed (timeout, &publish_timeout, po);
459}
460
461
462/* ************************** download ************************ */
463
464
465/**
466 * Task scheduled to run when download operation times out.
467 *
468 * @param cls the download operation context
469 */
470static void
471download_timeout (void *cls)
472{
473 struct TestDownloadOperation *dop = cls;
474
475 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
476 "Timeout while trying to download file\n");
477 dop->download_timeout_task = NULL;
478 GNUNET_FS_download_stop (dop->download_context,
479 GNUNET_YES);
480 GNUNET_SCHEDULER_add_now (dop->download_cont,
481 dop->download_cont_cls);
482 GNUNET_TESTBED_operation_done (dop->fs_op);
483 GNUNET_FS_uri_destroy (dop->uri);
484 GNUNET_free (dop);
485}
486
487
488/**
489 * Task scheduled to report on the completion of our download operation.
490 *
491 * @param cls the download operation context
492 */
493static void
494report_success (void *cls)
495{
496 struct TestDownloadOperation *dop = cls;
497
498 GNUNET_FS_download_stop (dop->download_context,
499 GNUNET_YES);
500 GNUNET_SCHEDULER_add_now (dop->download_cont,
501 dop->download_cont_cls);
502 GNUNET_TESTBED_operation_done (dop->fs_op);
503 GNUNET_FS_uri_destroy (dop->uri);
504 GNUNET_free (dop);
505}
506
507
508/**
509 * Progress callback for file-sharing events while downloading.
510 *
511 * @param cls the download operation context
512 * @param info information about the event
513 */
514static void *
515download_progress_cb (void *cls,
516 const struct GNUNET_FS_ProgressInfo *info)
517{
518 struct TestDownloadOperation *dop = cls;
519
520 switch (info->status)
521 {
522 case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS:
523 if (dop->verbose)
524 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
525 "Download at %llu/%llu bytes\n",
526 (unsigned long long) info->value.download.completed,
527 (unsigned long long) info->value.download.size);
528 break;
529
530 case GNUNET_FS_STATUS_DOWNLOAD_COMPLETED:
531 GNUNET_SCHEDULER_cancel (dop->download_timeout_task);
532 dop->download_timeout_task = NULL;
533 GNUNET_SCHEDULER_add_now (&report_success, dop);
534 break;
535
536 case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE:
537 case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE:
538 break;
539
540 /* FIXME: monitor data correctness during download progress */
541 /* FIXME: do performance reports given sufficient verbosity */
542 /* FIXME: advance timeout task to "immediate" on error */
543 default:
544 break;
545 }
546 return NULL;
547}
548
549
550/**
551 * Connect adapter for download operation.
552 *
553 * @param cls the 'struct TestDownloadOperation'
554 * @param cfg configuration of the peer to connect to; will be available until
555 * GNUNET_TESTBED_operation_done() is called on the operation returned
556 * from GNUNET_TESTBED_service_connect()
557 * @return service handle to return in 'op_result', NULL on error
558 */
559static void *
560download_connect_adapter (void *cls,
561 const struct GNUNET_CONFIGURATION_Handle *cfg)
562{
563 struct TestPublishOperation *po = cls;
564
565 return GNUNET_FS_start (cfg,
566 "fs-test-download",
567 &download_progress_cb, po,
568 GNUNET_FS_FLAGS_NONE,
569 GNUNET_FS_OPTIONS_END);
570}
571
572
573/**
574 * Callback to be called when testbed has connected to the fs service
575 *
576 * @param cls the 'struct TestPublishOperation'
577 * @param op the operation that has been finished
578 * @param ca_result the 'struct GNUNET_FS_Handle ' (NULL on error)
579 * @param emsg error message in case the operation has failed; will be NULL if
580 * operation has executed successfully.
581 */
582static void
583download_fs_connect_complete_cb (void *cls,
584 struct GNUNET_TESTBED_Operation *op,
585 void *ca_result,
586 const char *emsg)
587{
588 struct TestDownloadOperation *dop = cls;
589
590 dop->fs = ca_result;
591 GNUNET_assert (NULL != dop->fs);
592 dop->download_context =
593 GNUNET_FS_download_start (dop->fs, dop->uri, NULL, NULL, NULL, 0, dop->size,
594 dop->anonymity, GNUNET_FS_DOWNLOAD_OPTION_NONE,
595 NULL, NULL);
596}
597
598
599void
600GNUNET_FS_TEST_download (struct GNUNET_TESTBED_Peer *peer,
601 struct GNUNET_TIME_Relative timeout,
602 uint32_t anonymity, uint32_t seed,
603 const struct GNUNET_FS_Uri *uri, unsigned int verbose,
604 GNUNET_SCHEDULER_TaskCallback cont, void *cont_cls)
605{
606 struct TestDownloadOperation *dop;
607
608 dop = GNUNET_new (struct TestDownloadOperation);
609 dop->uri = GNUNET_FS_uri_dup (uri);
610 dop->size = GNUNET_FS_uri_chk_get_file_size (uri);
611 dop->verbose = verbose;
612 dop->anonymity = anonymity;
613 dop->download_cont = cont;
614 dop->download_cont_cls = cont_cls;
615 dop->download_seed = seed;
616
617 dop->fs_op = GNUNET_TESTBED_service_connect (dop,
618 peer,
619 "fs",
620 &download_fs_connect_complete_cb,
621 dop,
622 &download_connect_adapter,
623 &fs_disconnect_adapter,
624 dop);
625 dop->download_timeout_task =
626 GNUNET_SCHEDULER_add_delayed (timeout, &download_timeout, dop);
627}
628
629
630/* end of fs_test_lib.c */