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