more FS coding
[oweals/gnunet.git] / src / fs / test_fs_download.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/download_persistence_test.c
23  * @brief testcase for fsui download persistence (upload-download)
24  * @author Christian Grothoff
25  */
26
27 #include "platform.h"
28 #include "gnunet_util.h"
29 #include "gnunet_fsui_lib.h"
30
31 #define DEBUG_VERBOSE GNUNET_NO
32
33 #define CHECK(a) if (!(a)) { ok = GNUNET_NO; GNUNET_GE_BREAK(ectx, 0); goto FAILURE; }
34
35 static volatile int suspendRestart = 0;
36
37 static struct GNUNET_GE_Context *ectx;
38
39 static char *
40 makeName (unsigned int i)
41 {
42   char *fn;
43
44   fn =
45     GNUNET_malloc (strlen
46                    ("/tmp/gnunet-fsui-download_persistence_test/FSUITEST") +
47                    14);
48   GNUNET_snprintf (fn,
49                    strlen
50                    ("/tmp/gnunet-fsui-download_persistence_test/FSUITEST") +
51                    14,
52                    "/tmp/gnunet-fsui-download_persistence_test/FSUITEST%u",
53                    i);
54   GNUNET_disk_directory_create_for_file (NULL, fn);
55   return fn;
56 }
57
58 static volatile enum GNUNET_FSUI_EventType lastEvent;
59 static volatile enum GNUNET_FSUI_EventType waitForEvent;
60 static volatile int download_done;
61 static struct GNUNET_FSUI_Context *ctx;
62 static struct GNUNET_ECRS_URI *upURI;
63 static struct GNUNET_FSUI_DownloadList *download;
64
65 static void *
66 eventCallback (void *cls, const GNUNET_FSUI_Event * event)
67 {
68   switch (event->type)
69     {
70     case GNUNET_FSUI_download_suspended:
71       download = NULL;
72       break;
73     case GNUNET_FSUI_download_resumed:
74 #if DEBUG_VERBOSE
75       printf ("Download resuming\n");
76 #endif
77       download = event->data.DownloadResumed.dc.pos;
78       break;
79     case GNUNET_FSUI_upload_progress:
80 #if DEBUG_VERBOSE > 1
81       printf ("Upload is progressing (%llu/%llu)...\n",
82               event->data.UploadProgress.completed,
83               event->data.UploadProgress.total);
84 #endif
85       break;
86     case GNUNET_FSUI_upload_completed:
87       upURI = GNUNET_ECRS_uri_duplicate (event->data.UploadCompleted.uri);
88 #if DEBUG_VERBOSE
89       printf ("Upload complete.\n");
90 #endif
91       break;
92     case GNUNET_FSUI_download_completed:
93 #if DEBUG_VERBOSE
94       printf ("Download complete.\n");
95 #endif
96       download_done = 1;
97       break;
98     case GNUNET_FSUI_download_progress:
99 #if DEBUG_VERBOSE > 1
100       printf ("Download is progressing (%llu/%llu)...\n",
101               event->data.DownloadProgress.completed,
102               event->data.DownloadProgress.total);
103 #endif
104       break;
105     case GNUNET_FSUI_unindex_progress:
106 #if DEBUG_VERBOSE > 1
107       printf ("Unindex is progressing (%llu/%llu)...\n",
108               event->data.UnindexProgress.completed,
109               event->data.UnindexProgress.total);
110 #endif
111       break;
112     case GNUNET_FSUI_unindex_completed:
113 #if DEBUG_VERBOSE
114       printf ("Unindex complete.\n");
115 #endif
116       break;
117     case GNUNET_FSUI_unindex_error:
118     case GNUNET_FSUI_upload_error:
119     case GNUNET_FSUI_download_error:
120       fprintf (stderr, "Received ERROR: %d\n", event->type);
121       GNUNET_GE_BREAK (ectx, 0);
122       break;
123     case GNUNET_FSUI_download_aborted:
124 #if DEBUG_VERBOSE
125       printf ("Received download aborted event.\n");
126 #endif
127       break;
128     case GNUNET_FSUI_unindex_suspended:
129     case GNUNET_FSUI_upload_suspended:
130 #if DEBUG_VERBOSE
131       fprintf (stderr, "Received SUSPENDING: %d\n", event->type);
132 #endif
133       break;
134     case GNUNET_FSUI_upload_started:
135     case GNUNET_FSUI_upload_stopped:
136     case GNUNET_FSUI_download_started:
137     case GNUNET_FSUI_download_stopped:
138     case GNUNET_FSUI_unindex_started:
139     case GNUNET_FSUI_unindex_stopped:
140       break;
141     default:
142       printf ("Unexpected event: %d\n", event->type);
143       break;
144     }
145   if (lastEvent == waitForEvent)
146     return NULL;                /* ignore all other events */
147   lastEvent = event->type;
148   return NULL;
149 }
150
151 #define FILESIZE (1024 * 1024 * 2)
152
153 #define START_DAEMON 1
154
155 int
156 main (int argc, char *argv[])
157 {
158 #if START_DAEMON
159   pid_t daemon;
160 #endif
161   int ok;
162   int i;
163   char *fn = NULL;
164   char *keywords[] = {
165     "down_foo",
166     "down_bar",
167   };
168   int prog;
169   char *buf;
170   struct GNUNET_MetaData *meta = NULL;
171   struct GNUNET_ECRS_URI *kuri = NULL;
172   struct GNUNET_GC_Configuration *cfg;
173   struct GNUNET_FSUI_UnindexList *unindex = NULL;
174   struct GNUNET_FSUI_UploadList *upload = NULL;
175
176   ok = GNUNET_YES;
177   cfg = GNUNET_GC_create ();
178   if (-1 == GNUNET_GC_parse_configuration (cfg, "check.conf"))
179     {
180       GNUNET_GC_free (cfg);
181       return -1;
182     }
183 #if START_DAEMON
184   GNUNET_disk_directory_remove (NULL,
185                                 "/tmp/gnunet-fsui-download_persistence_test/");
186   daemon = GNUNET_daemon_start (NULL, cfg, "peer.conf", GNUNET_NO);
187   GNUNET_GE_ASSERT (NULL, daemon > 0);
188   CHECK (GNUNET_OK ==
189          GNUNET_wait_for_daemon_running (NULL, cfg,
190                                          30 * GNUNET_CRON_SECONDS));
191   GNUNET_thread_sleep (5 * GNUNET_CRON_SECONDS);        /* give apps time to start */
192   /* ACTUAL TEST CODE */
193 #endif
194   ctx = GNUNET_FSUI_start (NULL,
195                            cfg, "fsuidownload_persistence_test", 32,
196                            GNUNET_YES, &eventCallback, NULL);
197   CHECK (ctx != NULL);
198
199   /* upload */
200   fn = makeName (42);
201   buf = GNUNET_malloc (FILESIZE);
202   for (i = 0; i < FILESIZE; i++)
203     buf[i] = GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 256);
204   GNUNET_disk_file_write (ectx, fn, buf, FILESIZE, "600");
205   GNUNET_free (buf);
206   meta = GNUNET_meta_data_create ();
207   kuri =
208     GNUNET_ECRS_keyword_command_line_to_uri (ectx, 2,
209                                              (const char **) keywords);
210   waitForEvent = GNUNET_FSUI_upload_completed;
211   upload = GNUNET_FSUI_upload_start (ctx,
212                                      fn,
213                                      (GNUNET_FSUI_DirectoryScanCallback) &
214                                      GNUNET_disk_directory_scan, NULL, 0, 0,
215                                      GNUNET_YES, GNUNET_NO, GNUNET_NO,
216                                      GNUNET_get_time () +
217                                      5 * GNUNET_CRON_HOURS, meta, kuri, kuri);
218   CHECK (upload != NULL);
219   GNUNET_ECRS_uri_destroy (kuri);
220   kuri = NULL;
221   prog = 0;
222   while (lastEvent != GNUNET_FSUI_upload_completed)
223     {
224       prog++;
225       CHECK (prog < 5000);
226       GNUNET_thread_sleep (50 * GNUNET_CRON_MILLISECONDS);
227       if (GNUNET_shutdown_test () == GNUNET_YES)
228         break;
229     }
230   GNUNET_FSUI_upload_stop (upload);
231
232   /* download */
233   waitForEvent = GNUNET_FSUI_download_completed;
234   GNUNET_free (fn);
235   fn = makeName (43);
236   download_done = 0;
237   download = GNUNET_FSUI_download_start (ctx,
238                                          0,
239                                          GNUNET_NO,
240                                          upURI, meta, fn, NULL, NULL);
241   CHECK (download != NULL);
242   GNUNET_free (fn);
243   suspendRestart = 4;
244   prog = 0;
245   while (download_done == 0)
246     {
247       prog++;
248       CHECK (prog < 1000);
249       GNUNET_thread_sleep (50 * GNUNET_CRON_MILLISECONDS);
250       if ((suspendRestart > 0)
251           && (GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 4) == 0))
252         {
253 #if 1
254 #if DEBUG_VERBOSE
255           printf ("Testing FSUI suspend-resume\n");
256 #endif
257           GNUNET_FSUI_stop (ctx);       /* download possibly incomplete
258                                            at this point, thus testing resume */
259           ctx = GNUNET_FSUI_start (NULL,
260                                    cfg,
261                                    "fsuidownload_persistence_test",
262                                    32, GNUNET_YES, &eventCallback, NULL);
263 #if DEBUG_VERBOSE
264           printf ("Resumed...\n");
265 #endif
266 #endif
267           suspendRestart--;
268         }
269       if (GNUNET_shutdown_test () == GNUNET_YES)
270         break;
271     }
272   GNUNET_FSUI_download_stop (download);
273   download = NULL;
274
275   /* unindex */
276   waitForEvent = GNUNET_FSUI_unindex_completed;
277   fn = makeName (42);
278   unindex = GNUNET_FSUI_unindex_start (ctx, fn);
279   CHECK (unindex != NULL);
280   prog = 0;
281   while (lastEvent != GNUNET_FSUI_unindex_completed)
282     {
283       prog++;
284       CHECK (prog < 5000);
285       GNUNET_thread_sleep (50 * GNUNET_CRON_MILLISECONDS);
286       CHECK (lastEvent != GNUNET_FSUI_unindex_error);
287       if (GNUNET_shutdown_test () == GNUNET_YES)
288         break;
289     }
290   CHECK (lastEvent == GNUNET_FSUI_unindex_completed);
291   /* END OF TEST CODE */
292 FAILURE:
293   if (meta != NULL)
294     GNUNET_meta_data_destroy (meta);
295   if (ctx != NULL)
296     {
297       if (unindex != NULL)
298         GNUNET_FSUI_unindex_stop (unindex);
299       if (download != NULL)
300         GNUNET_FSUI_download_stop (download);
301       GNUNET_FSUI_stop (ctx);
302     }
303   if (fn != NULL)
304     {
305       UNLINK (fn);
306       GNUNET_free (fn);
307     }
308   if (kuri != NULL)
309     GNUNET_ECRS_uri_destroy (kuri);
310   fn = makeName (43);
311   /* TODO: verify file 'fn(42)' == file 'fn(43)' */
312   UNLINK (fn);
313   GNUNET_free (fn);
314   if (upURI != NULL)
315     GNUNET_ECRS_uri_destroy (upURI);
316
317 #if START_DAEMON
318   GNUNET_GE_BREAK (NULL, GNUNET_OK == GNUNET_daemon_stop (NULL, daemon));
319 #endif
320   GNUNET_GC_free (cfg);
321   return (ok == GNUNET_YES) ? 0 : 1;
322 }
323
324 /* end of download_persistence_test.c */