stuff
[oweals/gnunet.git] / src / fs / test_fs_download_recursive.c
1 /*
2      This file is part of GNUnet.
3      (C) 2004, 2005, 2006, 2008 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 2, 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 /**
22  * @file applications/fs/fsui/recursive_download_test.c
23  * @brief testcase for fsui recursive upload-download
24  * @author Christian Grothoff
25  * @author Heikki Lindholm
26  */
27
28 #include "platform.h"
29 #include "gnunet_util.h"
30 #include "gnunet_fsui_lib.h"
31
32 #define DEBUG_VERBOSE GNUNET_NO
33
34 #define CHECK(a) if (!(a)) { ok = GNUNET_NO; GNUNET_GE_BREAK(ectx, 0); goto FAILURE; }
35
36 #define FILESIZE (1024 * 1024 * 2)
37 /* depth-first directory tree d=dir f=file .=end of level*/
38 #define DIRECTORY_TREE_SPEC "dddf.f.d"
39
40 static struct GNUNET_GE_Context *ectx;
41
42 volatile int download_done;
43
44 static char *
45 makeName (unsigned int i)
46 {
47   char *fn;
48
49   fn =
50     GNUNET_malloc (strlen
51                    ("/tmp/gnunet-fsui-recursive_download_test/FSUITEST") +
52                    15);
53   GNUNET_snprintf (fn,
54                    strlen
55                    ("/tmp/gnunet-fsui-recursive_download_test/FSUITEST") + 15,
56                    "/tmp/gnunet-fsui-recursive_download_test/FSUITEST%u/", i);
57   return fn;
58 }
59
60 static int
61 makeHierarchyHelper (const char *current, const char *tree, int index,
62                      int check)
63 {
64   unsigned int fi, i;
65   int done;
66   char *s, *buf;
67
68   fi = 0;
69   done = 0;
70   while (!done && tree[index] != '\0')
71     {
72       s = GNUNET_malloc (strlen (current) + strlen (DIR_SEPARATOR_STR) + 14);
73       GNUNET_snprintf (s, strlen (current) + strlen (DIR_SEPARATOR_STR) + 14,
74                        "%s%s%u", current, DIR_SEPARATOR_STR, fi);
75       switch (tree[index++])
76         {
77         case 'd':
78           if (check)
79             {
80               if (GNUNET_disk_directory_test (NULL, s) == GNUNET_NO)
81                 {
82                   index = -1;
83                   done = 1;
84                 }
85             }
86           else
87             {
88               GNUNET_disk_directory_create (NULL, s);
89             }
90           if (!done)
91             index = makeHierarchyHelper (s, tree, index, check);
92           break;
93         case 'f':
94           if (check)
95             {
96               /* TODO: compare file contents */
97               if (GNUNET_disk_directory_test (NULL, s) != GNUNET_NO)
98                 {
99                   index = -1;
100                   done = 1;
101                 }
102             }
103           else
104             {
105               buf = GNUNET_malloc (FILESIZE);
106               for (i = 0; i < FILESIZE; i++)
107                 buf[i] = GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 256);
108               GNUNET_disk_file_write (ectx, s, buf, FILESIZE, "600");
109               GNUNET_free (buf);
110             }
111           break;
112         case '.':
113           done = 1;
114           break;
115         default:
116           break;
117         }
118       GNUNET_free (s);
119       fi++;
120     }
121   return index;
122 }
123
124 static char *
125 makeHierarchy (unsigned int i, const char *tree)
126 {
127   char *fn;
128
129   fn = makeName (i);
130   makeHierarchyHelper (fn, tree, 0, 0);
131   return fn;
132 }
133
134 static int
135 checkHierarchy (unsigned int i, const char *tree)
136 {
137   char *fn;
138   int res;
139
140   fn = makeName (i);
141   if (GNUNET_disk_directory_test (NULL, fn) != GNUNET_YES)
142     {
143       GNUNET_free (fn);
144       return GNUNET_SYSERR;
145     }
146   res = ((makeHierarchyHelper (fn, tree, 0, 1) == -1) ?
147          GNUNET_SYSERR : GNUNET_OK);
148   GNUNET_free (fn);
149   return res;
150 }
151
152
153 static volatile enum GNUNET_FSUI_EventType lastEvent;
154 static volatile enum GNUNET_FSUI_EventType waitForEvent;
155 static struct GNUNET_FSUI_Context *ctx;
156 static struct GNUNET_ECRS_URI *upURI;
157 static struct GNUNET_FSUI_DownloadList *download;
158
159 static void *
160 eventCallback (void *cls, const GNUNET_FSUI_Event * event)
161 {
162   switch (event->type)
163     {
164     case GNUNET_FSUI_download_suspended:
165       download = NULL;
166       break;
167     case GNUNET_FSUI_download_resumed:
168       download = event->data.DownloadResumed.dc.pos;
169       break;
170       break;
171     case GNUNET_FSUI_upload_progress:
172 #if DEBUG_VERBOSE > 1
173       printf ("Upload is progressing (%llu/%llu)...\n",
174               event->data.UploadProgress.completed,
175               event->data.UploadProgress.total);
176 #endif
177       break;
178     case GNUNET_FSUI_upload_completed:
179       upURI = GNUNET_ECRS_uri_duplicate (event->data.UploadCompleted.uri);
180 #if DEBUG_VERBOSE
181       printf ("Upload of `%s' complete.\n",
182               event->data.UploadCompleted.filename);
183 #endif
184       break;
185     case GNUNET_FSUI_download_completed:
186 #if DEBUG_VERBOSE
187       printf ("Download of `%s' complete.\n",
188               event->data.DownloadCompleted.filename);
189 #endif
190       if (checkHierarchy (43, DIRECTORY_TREE_SPEC) == GNUNET_OK)
191         download_done = 1;
192 #if DEBUG_VERBOSE
193       else
194         printf ("Hierarchy check not successful yet...\n");
195 #endif
196       break;
197     case GNUNET_FSUI_download_progress:
198 #if DEBUG_VERBOSE > 1
199       printf ("Download is progressing (%llu/%llu)...\n",
200               event->data.DownloadProgress.completed,
201               event->data.DownloadProgress.total);
202 #endif
203       break;
204     case GNUNET_FSUI_unindex_progress:
205 #if DEBUG_VERBOSE > 1
206       printf ("Unindex is progressing (%llu/%llu)...\n",
207               event->data.UnindexProgress.completed,
208               event->data.UnindexProgress.total);
209 #endif
210       break;
211     case GNUNET_FSUI_unindex_completed:
212 #if DEBUG_VERBOSE
213       printf ("Unindex complete.\n");
214 #endif
215       break;
216     case GNUNET_FSUI_unindex_error:
217       fprintf (stderr, "Error unindexing: %s\n",
218                event->data.UnindexError.message);
219       break;
220     case GNUNET_FSUI_upload_error:
221       fprintf (stderr, "Error uploading: %s\n",
222                event->data.UploadError.message);
223       break;
224     case GNUNET_FSUI_download_error:
225       fprintf (stderr, "Error downloading: %s\n",
226                event->data.DownloadError.message);
227       break;
228     case GNUNET_FSUI_download_aborted:
229 #if DEBUG_VERBOSE
230       printf ("Received download aborted event.\n");
231 #endif
232       break;
233     case GNUNET_FSUI_unindex_suspended:
234     case GNUNET_FSUI_upload_suspended:
235     case GNUNET_FSUI_upload_started:
236     case GNUNET_FSUI_upload_stopped:
237     case GNUNET_FSUI_download_started:
238     case GNUNET_FSUI_download_stopped:
239     case GNUNET_FSUI_unindex_started:
240     case GNUNET_FSUI_unindex_stopped:
241       break;
242     default:
243       printf ("Unexpected event: %d\n", event->type);
244       break;
245     }
246   if (lastEvent == waitForEvent)
247     return NULL;                /* ignore all other events */
248   lastEvent = event->type;
249   return NULL;
250 }
251
252
253 #define START_DAEMON 1
254
255 int
256 main (int argc, char *argv[])
257 {
258 #if START_DAEMON
259   pid_t daemon;
260 #endif
261   int ok;
262   char *fn = NULL;
263   char *fn43 = NULL;
264   char *keywords[] = {
265     "down_foo",
266     "down_bar",
267   };
268   int prog;
269   struct GNUNET_MetaData *meta = NULL;
270   struct GNUNET_ECRS_URI *kuri = NULL;
271   struct GNUNET_GC_Configuration *cfg;
272   struct GNUNET_FSUI_UploadList *upload = NULL;
273
274   ok = GNUNET_YES;
275   cfg = GNUNET_GC_create ();
276   if (-1 == GNUNET_GC_parse_configuration (cfg, "check.conf"))
277     {
278       GNUNET_GC_free (cfg);
279       return -1;
280     }
281   fprintf(stderr,
282           "Setup...\n");
283 #if START_DAEMON
284   GNUNET_disk_directory_remove (NULL,
285                                 "/tmp/gnunet-fsui-recursive_download_test/");
286   daemon = GNUNET_daemon_start (NULL, cfg, "peer.conf", GNUNET_NO);
287   GNUNET_GE_ASSERT (NULL, daemon > 0);
288   CHECK (GNUNET_OK ==
289          GNUNET_wait_for_daemon_running (NULL, cfg,
290                                          30 * GNUNET_CRON_SECONDS));
291   GNUNET_thread_sleep (5 * GNUNET_CRON_SECONDS);        /* give apps time to start */
292   /* ACTUAL TEST CODE */
293 #endif
294   ctx = GNUNET_FSUI_start (NULL,
295                            cfg, "fsuirecursive_download_test", 32, GNUNET_YES,
296                            &eventCallback, NULL);
297   CHECK (ctx != NULL);
298   fn = makeHierarchy (42, DIRECTORY_TREE_SPEC);
299   meta = GNUNET_meta_data_create ();
300   kuri =
301     GNUNET_ECRS_keyword_command_line_to_uri (ectx, 2,
302                                              (const char **) keywords);
303   fprintf(stderr,
304           "Uploading...\n");
305   waitForEvent = GNUNET_FSUI_upload_completed;
306   upload = GNUNET_FSUI_upload_start (ctx,
307                                      fn,
308                                      (GNUNET_FSUI_DirectoryScanCallback) &
309                                      GNUNET_disk_directory_scan, NULL, 0, 0,
310                                      GNUNET_YES, GNUNET_NO, GNUNET_NO,
311                                      GNUNET_get_time () +
312                                      5 * GNUNET_CRON_HOURS, meta, kuri, kuri);
313   CHECK (upload != NULL);
314   GNUNET_ECRS_uri_destroy (kuri);
315   kuri = NULL;
316   prog = 0;
317   while (lastEvent != GNUNET_FSUI_upload_completed)
318     {
319       prog++;
320       CHECK (prog < 5000);
321       GNUNET_thread_sleep (50 * GNUNET_CRON_MILLISECONDS);
322       if (GNUNET_shutdown_test () == GNUNET_YES)
323         break;
324     }
325   GNUNET_FSUI_upload_stop (upload);
326   upload = NULL;
327   CHECK (upURI != NULL);
328
329   fprintf(stderr,
330           "Downloading...\n");
331   waitForEvent = GNUNET_FSUI_download_completed;
332   fn43 = makeName (43);
333   download = GNUNET_FSUI_download_start (ctx,
334                                          0,
335                                          GNUNET_YES,
336                                          upURI, meta, fn43, NULL, NULL);
337   CHECK (download != NULL);
338   GNUNET_free (fn43);
339   fn43 = NULL;
340   prog = 0;
341   while (!download_done)
342     {
343       prog++;
344       CHECK (prog < 5000);
345       GNUNET_thread_sleep (50 * GNUNET_CRON_MILLISECONDS);
346       if (GNUNET_shutdown_test () == GNUNET_YES)
347         break;
348     }
349 FAILURE:
350   fprintf(stderr,
351           "Cleanup...\n");
352   if (meta != NULL)
353     GNUNET_meta_data_destroy (meta);
354   if (ctx != NULL)
355     {
356       if (download != NULL)
357         GNUNET_FSUI_download_stop (download);
358       GNUNET_FSUI_stop (ctx);
359     }
360   if (fn != NULL)
361     {
362       GNUNET_disk_directory_remove (NULL, fn);
363       GNUNET_free (fn);
364     }
365   if (kuri != NULL)
366     GNUNET_ECRS_uri_destroy (kuri);
367   fn43 = makeName (43);
368   GNUNET_disk_directory_remove (NULL, fn43);
369   GNUNET_free (fn43);
370   if (upURI != NULL)
371     GNUNET_ECRS_uri_destroy (upURI);
372
373 #if START_DAEMON
374   GNUNET_GE_BREAK (NULL, GNUNET_OK == GNUNET_daemon_stop (NULL, daemon));
375 #endif
376   GNUNET_GC_free (cfg);
377   return (ok == GNUNET_YES) ? 0 : 1;
378 }
379
380 /* end of recursive_download_test.c */