glitch in the license text detected by hyazinthe, thank you!
[oweals/gnunet.git] / src / fs / test_fs_publish_persistence.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010 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 /**
16  * @file fs/test_fs_publish_persistence.c
17  * @brief simple testcase for persistence of simple publish operation
18  * @author Christian Grothoff
19  */
20 #include "platform.h"
21 #include "gnunet_util_lib.h"
22 #include "gnunet_testing_lib.h"
23 #include "gnunet_fs_service.h"
24
25
26 /**
27  * File-size we use for testing.
28  */
29 #define FILESIZE (1024 * 1024 * 2)
30
31 /**
32  * How long until we give up on transmitting the message?
33  */
34 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60)
35
36 /**
37  * How long should our test-content live?
38  */
39 #define LIFETIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
40
41
42 static struct GNUNET_TIME_Absolute start;
43
44 static struct GNUNET_FS_Handle *fs;
45
46 static const struct GNUNET_CONFIGURATION_Handle *cfg;
47
48 static struct GNUNET_FS_PublishContext *publish;
49
50 static struct GNUNET_FS_PublishContext *publish;
51
52 static char *fn1;
53
54 static char *fn2;
55
56 static int err;
57
58 static struct GNUNET_SCHEDULER_Task *rtask;
59
60
61 static void
62 abort_publish_task (void *cls)
63 {
64   GNUNET_FS_publish_stop (publish);
65   publish = NULL;
66   GNUNET_DISK_directory_remove (fn1);
67   GNUNET_free (fn1);
68   fn1 = NULL;
69   GNUNET_DISK_directory_remove (fn2);
70   GNUNET_free (fn2);
71   fn2 = NULL;
72   GNUNET_FS_stop (fs);
73   fs = NULL;
74   if (NULL != rtask)
75   {
76     GNUNET_SCHEDULER_cancel (rtask);
77     rtask = NULL;
78   }
79 }
80
81
82 static void *
83 progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event);
84
85
86 static void
87 restart_fs_task (void *cls)
88 {
89   rtask = NULL;
90   GNUNET_FS_stop (fs);
91   fs = GNUNET_FS_start (cfg, "test-fs-publish-persistence",
92                         &progress_cb, NULL,
93                         GNUNET_FS_FLAGS_PERSISTENCE,
94                         GNUNET_FS_OPTIONS_END);
95 }
96
97
98 /**
99  * Consider scheduling the restart-task.
100  * Only runs the restart task once per event
101  * category.
102  *
103  * @param ev type of the event to consider
104  */
105 static void
106 consider_restart (int ev)
107 {
108   static int prev[32];
109   static int off;
110   int i;
111
112   for (i = 0; i < off; i++)
113     if (prev[i] == ev)
114       return;
115   prev[off++] = ev;
116   rtask =
117       GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_URGENT,
118                                           &restart_fs_task, NULL);
119 }
120
121
122 static void *
123 progress_cb (void *cls,
124              const struct GNUNET_FS_ProgressInfo *event)
125 {
126   void *ret;
127
128   ret = NULL;
129   switch (event->status)
130   {
131   case GNUNET_FS_STATUS_PUBLISH_COMPLETED:
132     ret = event->value.publish.cctx;
133     printf ("Publish complete,  %llu kbps.\n",
134             (unsigned long long) (FILESIZE * 1000000LL /
135                                   (1 +
136                                    GNUNET_TIME_absolute_get_duration
137                                    (start).rel_value_us) / 1024));
138     if ( (NULL != event->value.publish.cctx) &&
139          (0 == strcmp ("publish-context-dir", event->value.publish.cctx)) )
140       GNUNET_SCHEDULER_add_now (&abort_publish_task, NULL);
141     break;
142   case GNUNET_FS_STATUS_PUBLISH_PROGRESS_DIRECTORY:
143     ret = event->value.publish.cctx;
144     return ret;
145   case GNUNET_FS_STATUS_PUBLISH_PROGRESS:
146     consider_restart (event->status);
147     ret = event->value.publish.cctx;
148     GNUNET_assert (publish == event->value.publish.pc);
149 #if VERBOSE
150     printf ("Publish is progressing (%llu/%llu at level %u off %llu)...\n",
151             (unsigned long long) event->value.publish.completed,
152             (unsigned long long) event->value.publish.size,
153             event->value.publish.specifics.progress.depth,
154             (unsigned long long) event->value.publish.specifics.
155             progress.offset);
156 #endif
157     break;
158   case GNUNET_FS_STATUS_PUBLISH_SUSPEND:
159     if (event->value.publish.pc == publish)
160       publish = NULL;
161     break;
162   case GNUNET_FS_STATUS_PUBLISH_RESUME:
163     if (NULL == publish)
164     {
165       GNUNET_assert (GNUNET_YES ==
166                      GNUNET_FS_file_information_is_directory (event->
167                                                               value.publish.
168                                                               fi));
169       publish = event->value.publish.pc;
170       return "publish-context-dir";
171     }
172     break;
173   case GNUNET_FS_STATUS_PUBLISH_ERROR:
174     ret = event->value.publish.cctx;
175     FPRINTF (stderr, "Error publishing file: %s\n",
176              event->value.publish.specifics.error.message);
177     err = 1;
178     GNUNET_SCHEDULER_add_now (&abort_publish_task, NULL);
179     break;
180   case GNUNET_FS_STATUS_PUBLISH_START:
181     consider_restart (event->status);
182     publish = event->value.publish.pc;
183     ret = event->value.publish.cctx;
184     if (0 == strcmp ("publish-context1", event->value.publish.cctx))
185     {
186       GNUNET_assert (0 ==
187                      strcmp ("publish-context-dir", event->value.publish.pctx));
188       GNUNET_assert (FILESIZE == event->value.publish.size);
189       GNUNET_assert (0 == event->value.publish.completed);
190       GNUNET_assert (1 == event->value.publish.anonymity);
191     }
192     else if (0 == strcmp ("publish-context2", event->value.publish.cctx))
193     {
194       GNUNET_assert (0 ==
195                      strcmp ("publish-context-dir", event->value.publish.pctx));
196       GNUNET_assert (FILESIZE == event->value.publish.size);
197       GNUNET_assert (0 == event->value.publish.completed);
198       GNUNET_assert (2 == event->value.publish.anonymity);
199     }
200     else if (0 == strcmp ("publish-context-dir", event->value.publish.cctx))
201     {
202       GNUNET_assert (0 == event->value.publish.completed);
203       GNUNET_assert (3 == event->value.publish.anonymity);
204     }
205     else
206       GNUNET_assert (0);
207     break;
208   case GNUNET_FS_STATUS_PUBLISH_STOPPED:
209     consider_restart (event->status);
210     if ( (NULL != event->value.publish.cctx) &&
211          (0 == strcmp ("publish-context-dir", event->value.publish.cctx)) )
212       GNUNET_assert (publish == event->value.publish.pc);
213     break;
214   default:
215     printf ("Unexpected event: %d\n", event->status);
216     break;
217   }
218   return ret;
219 }
220
221
222 static void
223 run (void *cls,
224      const struct GNUNET_CONFIGURATION_Handle *c,
225      struct GNUNET_TESTING_Peer *peer)
226 {
227   const char *keywords[] = {
228     "down_foo",
229     "down_bar",
230   };
231   char *buf;
232   struct GNUNET_CONTAINER_MetaData *meta;
233   struct GNUNET_FS_Uri *kuri;
234   struct GNUNET_FS_FileInformation *fi1;
235   struct GNUNET_FS_FileInformation *fi2;
236   struct GNUNET_FS_FileInformation *fidir;
237   size_t i;
238   struct GNUNET_FS_BlockOptions bo;
239
240   cfg = c;
241   fs = GNUNET_FS_start (cfg, "test-fs-publish-persistence", &progress_cb, NULL,
242                         GNUNET_FS_FLAGS_PERSISTENCE, GNUNET_FS_OPTIONS_END);
243   GNUNET_assert (NULL != fs);
244   fn1 = GNUNET_DISK_mktemp ("gnunet-publish-test-dst");
245   buf = GNUNET_malloc (FILESIZE);
246   for (i = 0; i < FILESIZE; i++)
247     buf[i] = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 256);
248   GNUNET_assert (FILESIZE ==
249                  GNUNET_DISK_fn_write (fn1, buf, FILESIZE,
250                                        GNUNET_DISK_PERM_USER_READ |
251                                        GNUNET_DISK_PERM_USER_WRITE));
252   GNUNET_free (buf);
253
254   fn2 = GNUNET_DISK_mktemp ("gnunet-publish-test-dst");
255   buf = GNUNET_malloc (FILESIZE);
256   for (i = 0; i < FILESIZE; i++)
257     buf[i] = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 256);
258   GNUNET_assert (FILESIZE ==
259                  GNUNET_DISK_fn_write (fn2, buf, FILESIZE,
260                                        GNUNET_DISK_PERM_USER_READ |
261                                        GNUNET_DISK_PERM_USER_WRITE));
262   GNUNET_free (buf);
263
264   meta = GNUNET_CONTAINER_meta_data_create ();
265   kuri = GNUNET_FS_uri_ksk_create_from_args (2, keywords);
266   bo.content_priority = 42;
267   bo.anonymity_level = 1;
268   bo.replication_level = 0;
269   bo.expiration_time = GNUNET_TIME_relative_to_absolute (LIFETIME);
270   fi1 =
271       GNUNET_FS_file_information_create_from_file (fs, "publish-context1", fn1,
272                                                    kuri, meta, GNUNET_YES, &bo);
273   GNUNET_assert (NULL != fi1);
274   bo.anonymity_level = 2;
275   fi2 =
276       GNUNET_FS_file_information_create_from_file (fs, "publish-context2", fn2,
277                                                    kuri, meta, GNUNET_YES, &bo);
278   GNUNET_assert (NULL != fi2);
279   bo.anonymity_level = 3;
280   fidir =
281       GNUNET_FS_file_information_create_empty_directory (fs,
282                                                          "publish-context-dir",
283                                                          kuri, meta, &bo, NULL);
284   GNUNET_assert (GNUNET_OK == GNUNET_FS_file_information_add (fidir, fi1));
285   GNUNET_assert (GNUNET_OK == GNUNET_FS_file_information_add (fidir, fi2));
286   GNUNET_FS_uri_destroy (kuri);
287   GNUNET_CONTAINER_meta_data_destroy (meta);
288   GNUNET_assert (NULL != fidir);
289   start = GNUNET_TIME_absolute_get ();
290   GNUNET_FS_publish_start (fs, fidir, NULL, NULL, NULL,
291                            GNUNET_FS_PUBLISH_OPTION_NONE);
292   GNUNET_assert (publish != NULL);
293 }
294
295
296 int
297 main (int argc, char *argv[])
298 {
299   if (0 != GNUNET_TESTING_peer_run ("test-fs-publish-persistence",
300                                     "test_fs_publish_data.conf",
301                                     &run, NULL))
302     return 1;
303   return err;
304 }
305
306 /* end of test_fs_publish_persistence.c */