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.c659
1 files changed, 0 insertions, 659 deletions
diff --git a/src/fs/fs_test_lib.c b/src/fs/fs_test_lib.c
deleted file mode 100644
index dc4b214d9..000000000
--- a/src/fs/fs_test_lib.c
+++ /dev/null
@@ -1,659 +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 * @param tc scheduler context (unused)
181 */
182static void
183report_uri (void *cls)
184{
185 struct TestPublishOperation *po = cls;
186
187 GNUNET_FS_publish_stop (po->publish_context);
188 GNUNET_TESTBED_operation_done (po->fs_op);
189 po->publish_cont (po->publish_cont_cls,
190 po->publish_uri,
191 (GNUNET_YES == po->do_index)
192 ? po->publish_tmp_file
193 : NULL);
194 GNUNET_FS_uri_destroy (po->publish_uri);
195 if ((GNUNET_YES != po->do_index) &&
196 (NULL != po->publish_tmp_file))
197 (void) GNUNET_DISK_directory_remove (po->publish_tmp_file);
198 GNUNET_free (po->publish_tmp_file);
199 GNUNET_free (po);
200}
201
202
203/**
204 * Task scheduled to run when publish operation times out.
205 *
206 * @param cls the publish operation context
207 */
208static void
209publish_timeout (void *cls)
210{
211 struct TestPublishOperation *po = cls;
212
213 po->publish_timeout_task = NULL;
214 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
215 "Timeout while trying to publish data\n");
216 GNUNET_TESTBED_operation_done (po->fs_op);
217 GNUNET_FS_publish_stop (po->publish_context);
218 po->publish_cont (po->publish_cont_cls, NULL, NULL);
219 (void) GNUNET_DISK_directory_remove (po->publish_tmp_file);
220 GNUNET_free (po->publish_tmp_file);
221 GNUNET_free (po);
222}
223
224
225/**
226 * Progress callback for file-sharing events while publishing.
227 *
228 * @param cls the publish operation context
229 * @param info information about the event
230 */
231static void *
232publish_progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info)
233{
234 struct TestPublishOperation *po = cls;
235
236 switch (info->status)
237 {
238 case GNUNET_FS_STATUS_PUBLISH_COMPLETED:
239 GNUNET_SCHEDULER_cancel (po->publish_timeout_task);
240 po->publish_timeout_task = NULL;
241 po->publish_uri =
242 GNUNET_FS_uri_dup (info->value.publish.specifics.completed.chk_uri);
243 GNUNET_SCHEDULER_add_now (&report_uri,
244 po);
245 break;
246
247 case GNUNET_FS_STATUS_PUBLISH_PROGRESS:
248 if (po->verbose)
249 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Publishing at %llu/%llu bytes\n",
250 (unsigned long long) info->value.publish.completed,
251 (unsigned long long) info->value.publish.size);
252 break;
253
254 case GNUNET_FS_STATUS_PUBLISH_PROGRESS_DIRECTORY:
255 break;
256
257 case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS:
258 if (po->verbose)
259 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Download at %llu/%llu bytes\n",
260 (unsigned long long) info->value.download.completed,
261 (unsigned long long) info->value.download.size);
262 break;
263
264 default:
265 break;
266 }
267 return NULL;
268}
269
270
271/**
272 * Generate test data for publishing test.
273 *
274 * @param cls pointer to uint32_t with publishing seed
275 * @param offset offset to generate data for
276 * @param max maximum number of bytes to generate
277 * @param buf where to write generated data
278 * @param emsg where to store error message (unused)
279 * @return number of bytes written to buf
280 */
281static size_t
282file_generator (void *cls,
283 uint64_t offset,
284 size_t max,
285 void *buf,
286 char **emsg)
287{
288 uint32_t *publish_seed = cls;
289 uint64_t pos;
290 uint8_t *cbuf = buf;
291 int mod;
292
293 if (emsg != NULL)
294 *emsg = NULL;
295 if (buf == NULL)
296 return 0;
297 for (pos = 0; pos < 8; pos++)
298 cbuf[pos] = (uint8_t) (offset >> pos * 8);
299 for (pos = 8; pos < max; pos++)
300 {
301 mod = (255 - (offset / 1024 / 32));
302 if (mod == 0)
303 mod = 1;
304 cbuf[pos] = (uint8_t) ((offset * (*publish_seed)) % mod);
305 }
306 return max;
307}
308
309
310/**
311 * Connect adapter for publishing operation.
312 *
313 * @param cls the 'struct TestPublishOperation'
314 * @param cfg configuration of the peer to connect to; will be available until
315 * GNUNET_TESTBED_operation_done() is called on the operation returned
316 * from GNUNET_TESTBED_service_connect()
317 * @return service handle to return in 'op_result', NULL on error
318 */
319static void *
320publish_connect_adapter (void *cls,
321 const struct GNUNET_CONFIGURATION_Handle *cfg)
322{
323 struct TestPublishOperation *po = cls;
324
325 return GNUNET_FS_start (cfg,
326 "fs-test-publish",
327 &publish_progress_cb, po,
328 GNUNET_FS_FLAGS_NONE,
329 GNUNET_FS_OPTIONS_END);
330}
331
332
333/**
334 * Adapter function called to destroy connection to file-sharing service.
335 *
336 * @param cls the 'struct GNUNET_FS_Handle'
337 * @param op_result unused (different for publish/download!)
338 */
339static void
340fs_disconnect_adapter (void *cls,
341 void *op_result)
342{
343 struct GNUNET_FS_Handle *fs = op_result;
344
345 GNUNET_FS_stop (fs);
346}
347
348
349/**
350 * Callback to be called when testbed has connected to the fs service
351 *
352 * @param cls the 'struct TestPublishOperation'
353 * @param op the operation that has been finished
354 * @param ca_result the 'struct GNUNET_FS_Handle ' (NULL on error)
355 * @param emsg error message in case the operation has failed; will be NULL if
356 * operation has executed successfully.
357 */
358static void
359publish_fs_connect_complete_cb (void *cls,
360 struct GNUNET_TESTBED_Operation *op,
361 void *ca_result,
362 const char *emsg)
363{
364 struct TestPublishOperation *po = cls;
365 struct GNUNET_FS_FileInformation *fi;
366 struct GNUNET_DISK_FileHandle *fh;
367 char *em;
368 uint64_t off;
369 char buf[DBLOCK_SIZE];
370 size_t bsize;
371 struct GNUNET_FS_BlockOptions bo;
372
373 if (NULL == ca_result)
374 {
375 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
376 "Failed to connect to FS for publishing: %s\n", emsg);
377 po->publish_cont (po->publish_cont_cls,
378 NULL, NULL);
379 GNUNET_TESTBED_operation_done (po->fs_op);
380 GNUNET_free (po);
381 return;
382 }
383 po->fs = ca_result;
384
385 bo.expiration_time = GNUNET_TIME_relative_to_absolute (CONTENT_LIFETIME);
386 bo.anonymity_level = po->anonymity;
387 bo.content_priority = 42;
388 bo.replication_level = 1;
389 if (GNUNET_YES == po->do_index)
390 {
391 po->publish_tmp_file = GNUNET_DISK_mktemp ("fs-test-publish-index");
392 GNUNET_assert (po->publish_tmp_file != NULL);
393 fh = GNUNET_DISK_file_open (po->publish_tmp_file,
394 GNUNET_DISK_OPEN_WRITE
395 | GNUNET_DISK_OPEN_CREATE,
396 GNUNET_DISK_PERM_USER_READ
397 | GNUNET_DISK_PERM_USER_WRITE);
398 GNUNET_assert (NULL != fh);
399 off = 0;
400 while (off < po->size)
401 {
402 bsize = GNUNET_MIN (sizeof(buf), po->size - off);
403 emsg = NULL;
404 GNUNET_assert (bsize == file_generator (&po->publish_seed, off, bsize,
405 buf, &em));
406 GNUNET_assert (em == NULL);
407 GNUNET_assert (bsize == GNUNET_DISK_file_write (fh, buf, bsize));
408 off += bsize;
409 }
410 GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh));
411 fi = GNUNET_FS_file_information_create_from_file (po->fs, po,
412 po->publish_tmp_file,
413 NULL, NULL, po->do_index,
414 &bo);
415 GNUNET_assert (NULL != fi);
416 }
417 else
418 {
419 fi = GNUNET_FS_file_information_create_from_reader (po->fs, po,
420 po->size,
421 &file_generator,
422 &po->publish_seed,
423 NULL, NULL,
424 po->do_index, &bo);
425 GNUNET_assert (NULL != fi);
426 }
427 po->publish_context =
428 GNUNET_FS_publish_start (po->fs, fi, NULL, NULL, NULL,
429 GNUNET_FS_PUBLISH_OPTION_NONE);
430}
431
432
433/**
434 * Publish a file at the given peer.
435 *
436 * @param peer where to publish
437 * @param timeout if this operation cannot be completed within the
438 * given period, call the continuation with an error code
439 * @param anonymity option for publication
440 * @param do_index GNUNET_YES for index, GNUNET_NO for insertion,
441 * GNUNET_SYSERR for simulation
442 * @param size size of the file to publish
443 * @param seed seed to use for file generation
444 * @param verbose how verbose to be in reporting
445 * @param cont function to call when done
446 * @param cont_cls closure for cont
447 */
448void
449GNUNET_FS_TEST_publish (struct GNUNET_TESTBED_Peer *peer,
450 struct GNUNET_TIME_Relative timeout, uint32_t anonymity,
451 int do_index, uint64_t size, uint32_t seed,
452 unsigned int verbose,
453 GNUNET_FS_TEST_UriContinuation cont, void *cont_cls)
454{
455 struct TestPublishOperation *po;
456
457 po = GNUNET_new (struct TestPublishOperation);
458 po->publish_cont = cont;
459 po->publish_cont_cls = cont_cls;
460 po->publish_seed = seed;
461 po->anonymity = anonymity;
462 po->size = size;
463 po->verbose = verbose;
464 po->do_index = do_index;
465 po->fs_op = GNUNET_TESTBED_service_connect (po,
466 peer,
467 "fs",
468 &publish_fs_connect_complete_cb,
469 po,
470 &publish_connect_adapter,
471 &fs_disconnect_adapter,
472 po);
473 po->publish_timeout_task =
474 GNUNET_SCHEDULER_add_delayed (timeout, &publish_timeout, po);
475}
476
477
478/* ************************** download ************************ */
479
480
481/**
482 * Task scheduled to run when download operation times out.
483 *
484 * @param cls the download operation context
485 */
486static void
487download_timeout (void *cls)
488{
489 struct TestDownloadOperation *dop = cls;
490
491 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
492 "Timeout while trying to download file\n");
493 dop->download_timeout_task = NULL;
494 GNUNET_FS_download_stop (dop->download_context,
495 GNUNET_YES);
496 GNUNET_SCHEDULER_add_now (dop->download_cont,
497 dop->download_cont_cls);
498 GNUNET_TESTBED_operation_done (dop->fs_op);
499 GNUNET_FS_uri_destroy (dop->uri);
500 GNUNET_free (dop);
501}
502
503
504/**
505 * Task scheduled to report on the completion of our download operation.
506 *
507 * @param cls the download operation context
508 */
509static void
510report_success (void *cls)
511{
512 struct TestDownloadOperation *dop = cls;
513
514 GNUNET_FS_download_stop (dop->download_context,
515 GNUNET_YES);
516 GNUNET_SCHEDULER_add_now (dop->download_cont,
517 dop->download_cont_cls);
518 GNUNET_TESTBED_operation_done (dop->fs_op);
519 GNUNET_FS_uri_destroy (dop->uri);
520 GNUNET_free (dop);
521}
522
523
524/**
525 * Progress callback for file-sharing events while downloading.
526 *
527 * @param cls the download operation context
528 * @param info information about the event
529 */
530static void *
531download_progress_cb (void *cls,
532 const struct GNUNET_FS_ProgressInfo *info)
533{
534 struct TestDownloadOperation *dop = cls;
535
536 switch (info->status)
537 {
538 case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS:
539 if (dop->verbose)
540 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
541 "Download at %llu/%llu bytes\n",
542 (unsigned long long) info->value.download.completed,
543 (unsigned long long) info->value.download.size);
544 break;
545
546 case GNUNET_FS_STATUS_DOWNLOAD_COMPLETED:
547 GNUNET_SCHEDULER_cancel (dop->download_timeout_task);
548 dop->download_timeout_task = NULL;
549 GNUNET_SCHEDULER_add_now (&report_success, dop);
550 break;
551
552 case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE:
553 case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE:
554 break;
555
556 /* FIXME: monitor data correctness during download progress */
557 /* FIXME: do performance reports given sufficient verbosity */
558 /* FIXME: advance timeout task to "immediate" on error */
559 default:
560 break;
561 }
562 return NULL;
563}
564
565
566/**
567 * Connect adapter for download operation.
568 *
569 * @param cls the 'struct TestDownloadOperation'
570 * @param cfg configuration of the peer to connect to; will be available until
571 * GNUNET_TESTBED_operation_done() is called on the operation returned
572 * from GNUNET_TESTBED_service_connect()
573 * @return service handle to return in 'op_result', NULL on error
574 */
575static void *
576download_connect_adapter (void *cls,
577 const struct GNUNET_CONFIGURATION_Handle *cfg)
578{
579 struct TestPublishOperation *po = cls;
580
581 return GNUNET_FS_start (cfg,
582 "fs-test-download",
583 &download_progress_cb, po,
584 GNUNET_FS_FLAGS_NONE,
585 GNUNET_FS_OPTIONS_END);
586}
587
588
589/**
590 * Callback to be called when testbed has connected to the fs service
591 *
592 * @param cls the 'struct TestPublishOperation'
593 * @param op the operation that has been finished
594 * @param ca_result the 'struct GNUNET_FS_Handle ' (NULL on error)
595 * @param emsg error message in case the operation has failed; will be NULL if
596 * operation has executed successfully.
597 */
598static void
599download_fs_connect_complete_cb (void *cls,
600 struct GNUNET_TESTBED_Operation *op,
601 void *ca_result,
602 const char *emsg)
603{
604 struct TestDownloadOperation *dop = cls;
605
606 dop->fs = ca_result;
607 GNUNET_assert (NULL != dop->fs);
608 dop->download_context =
609 GNUNET_FS_download_start (dop->fs, dop->uri, NULL, NULL, NULL, 0, dop->size,
610 dop->anonymity, GNUNET_FS_DOWNLOAD_OPTION_NONE,
611 NULL, NULL);
612}
613
614
615/**
616 * Perform test download.
617 *
618 * @param peer which peer to download from
619 * @param timeout if this operation cannot be completed within the
620 * given period, call the continuation with an error code
621 * @param anonymity option for download
622 * @param seed used for file validation
623 * @param uri URI of file to download (CHK/LOC only)
624 * @param verbose how verbose to be in reporting
625 * @param cont function to call when done
626 * @param cont_cls closure for cont
627 */
628void
629GNUNET_FS_TEST_download (struct GNUNET_TESTBED_Peer *peer,
630 struct GNUNET_TIME_Relative timeout,
631 uint32_t anonymity, uint32_t seed,
632 const struct GNUNET_FS_Uri *uri, unsigned int verbose,
633 GNUNET_SCHEDULER_TaskCallback cont, void *cont_cls)
634{
635 struct TestDownloadOperation *dop;
636
637 dop = GNUNET_new (struct TestDownloadOperation);
638 dop->uri = GNUNET_FS_uri_dup (uri);
639 dop->size = GNUNET_FS_uri_chk_get_file_size (uri);
640 dop->verbose = verbose;
641 dop->anonymity = anonymity;
642 dop->download_cont = cont;
643 dop->download_cont_cls = cont_cls;
644 dop->download_seed = seed;
645
646 dop->fs_op = GNUNET_TESTBED_service_connect (dop,
647 peer,
648 "fs",
649 &download_fs_connect_complete_cb,
650 dop,
651 &download_connect_adapter,
652 &fs_disconnect_adapter,
653 dop);
654 dop->download_timeout_task =
655 GNUNET_SCHEDULER_add_delayed (timeout, &download_timeout, dop);
656}
657
658
659/* end of fs_test_lib.c */