868c9d71ad5f2ba4094b596da430cd0870b0f30c
[oweals/gnunet.git] / src / fs / test_fs_list_indexed.c
1 /*
2      This file is part of GNUnet.
3      (C) 2004, 2005, 2006, 2008, 2009 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 fs/test_fs_list_indexed.c
23  * @brief simple testcase for list_indexed operation (indexing, listing
24  *        indexed)
25  * @author Christian Grothoff
26  *
27  * TODO:
28  * - actually call list_indexed API!
29  */
30
31 #include "platform.h"
32 #include "gnunet_util_lib.h"
33 #include "gnunet_arm_service.h"
34 #include "gnunet_fs_service.h"
35
36 #define VERBOSE GNUNET_NO
37
38 #define START_ARM GNUNET_YES
39
40 /**
41  * File-size we use for testing.
42  */
43 #define FILESIZE (1024 * 1024 * 2)
44
45 /**
46  * How long until we give up on transmitting the message?
47  */
48 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15)
49
50 /**
51  * How long should our test-content live?
52  */ 
53 #define LIFETIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
54
55 struct PeerContext
56 {
57   struct GNUNET_CONFIGURATION_Handle *cfg;
58 #if START_ARM
59   pid_t arm_pid;
60 #endif
61 };
62
63 static struct PeerContext p1;
64
65 static struct GNUNET_TIME_Absolute start;
66
67 static struct GNUNET_SCHEDULER_Handle *sched;
68
69 static struct GNUNET_FS_Handle *fs;
70
71 static struct GNUNET_FS_PublishContext *publish;
72
73 static char *fn1;
74
75 static char *fn2;
76
77 static int err;
78
79 static void
80 abort_publish_task (void *cls,
81                     const struct GNUNET_SCHEDULER_TaskContext *tc)
82 {
83   GNUNET_FS_publish_stop (publish);
84   publish = NULL;
85   GNUNET_DISK_directory_remove (fn1);
86   GNUNET_free (fn1);
87   fn1 = NULL;
88   GNUNET_DISK_directory_remove (fn2);
89   GNUNET_free (fn2);
90   fn2 = NULL;
91 }
92
93
94 static void
95 list_indexed_task (void *cls,
96                    const struct GNUNET_SCHEDULER_TaskContext *tc)
97 {
98
99   GNUNET_SCHEDULER_add_continuation (sched,
100                                      GNUNET_NO,
101                                      &abort_publish_task,
102                                      NULL,
103                                      GNUNET_SCHEDULER_REASON_PREREQ_DONE);
104 }
105
106
107 static void *
108 progress_cb (void *cls, 
109              const struct GNUNET_FS_ProgressInfo *event)
110 {
111   void *ret;
112
113   ret = NULL;
114   switch (event->status)
115     {
116     case GNUNET_FS_STATUS_PUBLISH_COMPLETED:
117       ret = event->value.publish.cctx;
118       printf ("Publish complete,  %llu kbps.\n",
119               (unsigned long long) (FILESIZE * 1000 / (1+GNUNET_TIME_absolute_get_duration (start).value) / 1024));
120       if (0 == strcmp ("list_indexed-context-dir", 
121                        event->value.publish.cctx))      
122         GNUNET_SCHEDULER_add_continuation (sched,
123                                            GNUNET_NO,
124                                            &list_indexed_task,
125                                            NULL,
126                                            GNUNET_SCHEDULER_REASON_PREREQ_DONE);
127         
128       break;
129     case GNUNET_FS_STATUS_PUBLISH_PROGRESS:
130       ret = event->value.publish.cctx;
131       GNUNET_assert (publish == event->value.publish.sc);
132 #if VERBOSE
133       printf ("Publish is progressing (%llu/%llu at level %u off %llu)...\n",
134               (unsigned long long) event->value.publish.completed,
135               (unsigned long long) event->value.publish.size,
136               event->value.publish.specifics.progress.depth,
137               (unsigned long long) event->value.publish.specifics.progress.offset);
138 #endif
139       break;
140     case GNUNET_FS_STATUS_PUBLISH_ERROR:
141       ret = event->value.publish.cctx;
142       fprintf (stderr,
143                "Error publishing file: %s\n",
144                event->value.publish.specifics.error.message);
145       err = 1;
146       if (0 == strcmp ("list_indexed-context-dir", 
147                        event->value.publish.cctx))              
148         GNUNET_SCHEDULER_add_continuation (sched,
149                                            GNUNET_NO,
150                                            &abort_publish_task,
151                                            NULL,
152                                            GNUNET_SCHEDULER_REASON_PREREQ_DONE);
153       break;
154     case GNUNET_FS_STATUS_PUBLISH_START:
155       ret = event->value.publish.cctx;
156       if (0 == strcmp ("list_indexed-context1", 
157                        event->value.publish.cctx))
158         {
159           GNUNET_assert (0 == strcmp ("list_indexed-context-dir", 
160                                       event->value.publish.pctx));
161           GNUNET_assert (FILESIZE == event->value.publish.size);
162           GNUNET_assert (0 == event->value.publish.completed);
163           GNUNET_assert (1 == event->value.publish.anonymity);
164         }
165       else if (0 == strcmp ("list_indexed-context2", 
166                             event->value.publish.cctx))
167         {
168           GNUNET_assert (0 == strcmp ("list_indexed-context-dir", 
169                                       event->value.publish.pctx));
170           GNUNET_assert (FILESIZE == event->value.publish.size);
171           GNUNET_assert (0 == event->value.publish.completed);
172           GNUNET_assert (2 == event->value.publish.anonymity);
173         }
174       else if (0 == strcmp ("list_indexed-context-dir", 
175                             event->value.publish.cctx))
176         {
177           GNUNET_assert (0 == event->value.publish.completed);
178           GNUNET_assert (3 == event->value.publish.anonymity);
179         }
180       else
181         GNUNET_assert (0);
182       break;
183     case GNUNET_FS_STATUS_PUBLISH_STOPPED:
184       if (0 == strcmp ("list_indexed-context-dir", 
185                        event->value.publish.cctx))      
186         {
187           GNUNET_assert (publish == event->value.publish.sc);
188           publish = NULL;
189         }
190       break;
191     default:
192       printf ("Unexpected event: %d\n", 
193               event->status);
194       break;
195     }
196   return ret;
197 }
198
199
200 static void
201 setup_peer (struct PeerContext *p, const char *cfgname)
202 {
203   p->cfg = GNUNET_CONFIGURATION_create ();
204 #if START_ARM
205   p->arm_pid = GNUNET_OS_start_process ("gnunet-service-arm",
206                                         "gnunet-service-arm",
207 #if VERBOSE
208                                         "-L", "DEBUG",
209 #endif
210                                         "-c", cfgname, NULL);
211   sleep (1);                    /* allow ARM to start */
212 #endif
213   GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname));
214   GNUNET_ARM_start_services (p->cfg, sched, "core", NULL);
215 }
216
217
218 static void
219 stop_arm (struct PeerContext *p)
220 {
221 #if START_ARM
222   if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
223     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
224   if (GNUNET_OS_process_wait(p->arm_pid) != GNUNET_OK)
225     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
226   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
227               "ARM process %u stopped\n", p->arm_pid);
228 #endif
229   GNUNET_CONFIGURATION_destroy (p->cfg);
230 }
231
232
233 static void
234 run (void *cls,
235      struct GNUNET_SCHEDULER_Handle *s,
236      char *const *args,
237      const char *cfgfile,
238      const struct GNUNET_CONFIGURATION_Handle *cfg)
239 {
240   const char *keywords[] = {
241     "down_foo",
242     "down_bar",
243   };
244   char *buf;
245   struct GNUNET_CONTAINER_MetaData *meta;
246   struct GNUNET_FS_Uri *kuri;
247   struct GNUNET_FS_FileInformation *fi1;
248   struct GNUNET_FS_FileInformation *fi2;
249   struct GNUNET_FS_FileInformation *fidir;
250   size_t i;
251
252   sched = s;
253   setup_peer (&p1, "test_fs_list_indexed_data.conf");
254   fs = GNUNET_FS_start (sched,
255                         cfg,
256                         "test-fs-list_indexed",
257                         &progress_cb,
258                         NULL,
259                         GNUNET_FS_FLAGS_NONE,
260                         GNUNET_FS_OPTIONS_END);
261   GNUNET_assert (NULL != fs); 
262   fn1 = GNUNET_DISK_mktemp ("gnunet-list_indexed-test-dst");
263   buf = GNUNET_malloc (FILESIZE);
264   for (i = 0; i < FILESIZE; i++)
265     buf[i] = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 256);
266   GNUNET_assert (FILESIZE ==
267                  GNUNET_DISK_fn_write (fn1,
268                                        buf,
269                                        FILESIZE,
270                                        GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE));
271   GNUNET_free (buf);
272
273   fn2 = GNUNET_DISK_mktemp ("gnunet-list_indexed-test-dst");
274   buf = GNUNET_malloc (FILESIZE);
275   for (i = 0; i < FILESIZE; i++)
276     buf[i] = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 256);
277   GNUNET_assert (FILESIZE ==
278                  GNUNET_DISK_fn_write (fn2,
279                                        buf,
280                                        FILESIZE,
281                                        GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE));
282   GNUNET_free (buf);
283
284   meta = GNUNET_CONTAINER_meta_data_create ();
285   kuri = GNUNET_FS_uri_ksk_create_from_args (2, keywords);
286   fi1 = GNUNET_FS_file_information_create_from_file ("list_indexed-context1",
287                                                      fn1,
288                                                      kuri,
289                                                      meta,
290                                                      GNUNET_YES,
291                                                      1,
292                                                      42,
293                                                      GNUNET_TIME_relative_to_absolute (LIFETIME)); 
294   fi2 = GNUNET_FS_file_information_create_from_file ("list_indexed-context2",
295                                                      fn2,
296                                                      kuri,
297                                                      meta,
298                                                      GNUNET_YES,
299                                                      2,
300                                                      42,
301                                                      GNUNET_TIME_relative_to_absolute (LIFETIME)); 
302   fidir = GNUNET_FS_file_information_create_empty_directory ("list_indexed-context-dir",
303                                                              kuri,
304                                                              meta,
305                                                              3,
306                                                              42,
307                                                              GNUNET_TIME_relative_to_absolute (LIFETIME)); 
308   GNUNET_assert (GNUNET_OK == GNUNET_FS_file_information_add (fidir, fi1));
309   GNUNET_assert (GNUNET_OK == GNUNET_FS_file_information_add (fidir, fi2));
310   GNUNET_FS_uri_destroy (kuri);
311   GNUNET_CONTAINER_meta_data_destroy (meta);
312   GNUNET_assert (NULL != fidir);
313   start = GNUNET_TIME_absolute_get ();
314   publish = GNUNET_FS_publish_start (fs,
315                                      fidir,
316                                      NULL, NULL, NULL,
317                                      GNUNET_FS_PUBLISH_OPTION_NONE);
318   GNUNET_assert (publish != NULL);
319 }
320
321
322 int
323 main (int argc, char *argv[])
324 {
325   char *const argvx[] = { 
326     "test-fs-list_indexed",
327     "-c",
328     "test_fs_list_indexed_data.conf",
329 #if VERBOSE
330     "-L", "DEBUG",
331 #endif
332     NULL
333   };
334   struct GNUNET_GETOPT_CommandLineOption options[] = {
335     GNUNET_GETOPT_OPTION_END
336   };
337
338   GNUNET_log_setup ("test_fs_list_indexed", 
339 #if VERBOSE
340                     "DEBUG",
341 #else
342                     "WARNING",
343 #endif
344                     NULL);
345   GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1,
346                       argvx, "test-fs-list_indexed",
347                       "nohelp", options, &run, NULL);
348   stop_arm (&p1);
349   GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-list-indexed/");
350   GNUNET_DISK_directory_remove (fn1);
351   GNUNET_free_non_null (fn1);
352   GNUNET_DISK_directory_remove (fn2);
353   GNUNET_free_non_null (fn2);
354   return err;
355 }
356
357 /* end of test_fs_list_indexed.c */