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