resume and less debug crap
[oweals/gnunet.git] / src / fs / test_fs_namespace.c
1 /*
2      This file is part of GNUnet.
3      (C) 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_namespace.c
23  * @brief Test for fs_namespace.c
24  * @author Christian Grothoff
25  *
26  * TODO:
27  * - add timeout task
28  */
29 #include "platform.h"
30 #include "gnunet_util_lib.h"
31 #include "gnunet_arm_service.h"
32 #include "gnunet_fs_service.h"
33
34 #define VERBOSE GNUNET_NO
35
36 #define START_ARM GNUNET_YES
37
38 static struct GNUNET_SCHEDULER_Handle *sched;
39
40 static struct PeerContext p1;
41
42 static GNUNET_HashCode nsid;
43
44 static struct GNUNET_FS_Uri *sks_expect_uri;
45
46 static struct GNUNET_FS_Uri *ksk_expect_uri;
47
48 static struct GNUNET_FS_Handle *fs;
49
50 static struct GNUNET_FS_SearchContext *sks_search;
51
52 static struct GNUNET_FS_SearchContext *ksk_search;
53
54 static int update_started;
55
56 static int err;
57
58 struct PeerContext
59 {
60   struct GNUNET_CONFIGURATION_Handle *cfg;
61 #if START_ARM
62   pid_t arm_pid;
63 #endif
64 };
65
66
67 static void
68 setup_peer (struct PeerContext *p, const char *cfgname)
69 {
70   p->cfg = GNUNET_CONFIGURATION_create ();
71 #if START_ARM
72   p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
73                                         "gnunet-service-arm",
74 #if VERBOSE
75                                         "-L", "DEBUG",
76 #endif
77                                         "-c", cfgname, NULL);
78 #endif
79   GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname));
80 }
81
82
83 static void
84 stop_arm (struct PeerContext *p)
85 {
86 #if START_ARM
87   if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
88     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
89   if (GNUNET_OS_process_wait(p->arm_pid) != GNUNET_OK)
90     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
91   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
92               "ARM process %u stopped\n", p->arm_pid);
93 #endif
94   GNUNET_CONFIGURATION_destroy (p->cfg);
95 }
96
97
98 static void
99 abort_ksk_search_task (void *cls,
100                        const struct GNUNET_SCHEDULER_TaskContext *tc)
101 {
102   if (ksk_search != NULL)
103     {
104       GNUNET_FS_search_stop (ksk_search);
105       ksk_search = NULL;
106       if (sks_search == NULL)
107         {
108           GNUNET_FS_stop (fs);
109         }
110     }
111 }
112
113
114 static void
115 abort_sks_search_task (void *cls,
116                        const struct GNUNET_SCHEDULER_TaskContext *tc)
117 {
118   struct GNUNET_FS_Namespace *ns;
119
120   if (sks_search == NULL)
121     return;
122   GNUNET_FS_search_stop (sks_search); 
123   sks_search = NULL;
124   ns = GNUNET_FS_namespace_create (fs,
125                                    "testNamespace");
126   GNUNET_assert (GNUNET_OK == GNUNET_FS_namespace_delete (ns, GNUNET_YES));
127   if (ksk_search == NULL)
128     {
129       GNUNET_FS_stop (fs);
130     }    
131 }
132
133
134 static void *
135 progress_cb (void *cls, 
136              const struct GNUNET_FS_ProgressInfo *event)
137 {
138   switch (event->status)
139     {
140     case GNUNET_FS_STATUS_SEARCH_RESULT:
141       if (sks_search == event->value.search.sc)
142         {
143           if (! GNUNET_FS_uri_test_equal (sks_expect_uri,
144                                           event->value.search.specifics.result.uri))
145             {
146               fprintf (stderr,
147                        "Wrong result for sks search!\n");
148               err = 1;
149             }
150           /* give system 1ms to initiate update search! */
151           GNUNET_SCHEDULER_add_delayed (sched,
152                                         GNUNET_TIME_UNIT_MILLISECONDS,
153                                         &abort_sks_search_task,
154                                         NULL);
155         }
156       else if (ksk_search == event->value.search.sc)
157         {
158           if (! GNUNET_FS_uri_test_equal (ksk_expect_uri,
159                                           event->value.search.specifics.result.uri))
160             {
161               fprintf (stderr,
162                        "Wrong result for ksk search!\n");
163               err = 1;
164             }
165           GNUNET_SCHEDULER_add_continuation (sched,
166                                              &abort_ksk_search_task,
167                                              NULL,
168                                              GNUNET_SCHEDULER_REASON_PREREQ_DONE);
169         }
170       else 
171         {
172           fprintf (stderr,
173                    "Unexpected search result received!\n");
174           GNUNET_break (0);
175         }
176       break;
177     case GNUNET_FS_STATUS_SEARCH_ERROR:
178       fprintf (stderr,
179                "Error searching file: %s\n",
180                event->value.search.specifics.error.message);
181       if (sks_search == event->value.search.sc)
182         GNUNET_SCHEDULER_add_continuation (sched,
183                                            &abort_sks_search_task,
184                                            NULL,
185                                            GNUNET_SCHEDULER_REASON_PREREQ_DONE);
186       else if (ksk_search == event->value.search.sc)
187         GNUNET_SCHEDULER_add_continuation (sched,
188                                            &abort_ksk_search_task,
189                                            NULL,
190                                            GNUNET_SCHEDULER_REASON_PREREQ_DONE);
191       else
192         GNUNET_break (0);
193       break;
194     case GNUNET_FS_STATUS_SEARCH_START:
195       GNUNET_assert ( (NULL == event->value.search.cctx) ||
196                       (0 == strcmp ("sks_search", event->value.search.cctx)) ||
197                       (0 == strcmp ("ksk_search", event->value.search.cctx)));
198       if (NULL == event->value.search.cctx)
199         {
200           GNUNET_assert (0 == strcmp ("sks_search", event->value.search.pctx));
201           update_started = GNUNET_YES;
202         }
203       GNUNET_assert (1 == event->value.search.anonymity);
204       break;
205     case GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED:
206       return NULL;
207     case GNUNET_FS_STATUS_SEARCH_STOPPED:
208       return NULL;
209     default:
210       fprintf (stderr,
211                "Unexpected event: %d\n", 
212                event->status);
213       break;
214     }
215   return event->value.search.cctx;
216 }
217
218
219 static void
220 publish_cont (void *cls,
221               const struct GNUNET_FS_Uri *ksk_uri,
222               const char *emsg)
223 {
224   char *msg;
225   struct GNUNET_FS_Uri *sks_uri;
226   char sbuf[1024];
227   struct GNUNET_CRYPTO_HashAsciiEncoded enc;
228   
229   if (NULL != emsg)
230     {
231       fprintf (stderr, "Error publishing: %s\n", emsg);
232       err = 1;
233       GNUNET_FS_stop (fs);
234       return;
235     }  
236   GNUNET_CRYPTO_hash_to_enc (&nsid,
237                              &enc);
238   GNUNET_snprintf (sbuf,
239                    sizeof (sbuf),
240                    "gnunet://fs/sks/%s/this",
241                    &enc);
242   sks_uri = GNUNET_FS_uri_parse (sbuf, &msg);
243   if (msg != NULL)
244     {
245       fprintf (stderr, "failed to parse URI `%s': %s\n",
246                sbuf,
247                msg);
248       err = 1;
249       GNUNET_FS_stop (fs);
250       GNUNET_free (msg);
251       return;
252     }
253   ksk_search = GNUNET_FS_search_start (fs, ksk_uri, 1, "ksk_search");
254   sks_search = GNUNET_FS_search_start (fs, sks_uri, 1, "sks_search");
255   GNUNET_FS_uri_destroy (sks_uri);
256 }
257
258
259 static void
260 sks_cont (void *cls,
261           const struct GNUNET_FS_Uri *uri,
262           const char *emsg)
263 {
264   struct GNUNET_CONTAINER_MetaData *meta;
265   struct GNUNET_TIME_Absolute expiration;
266   struct GNUNET_FS_Uri *ksk_uri;
267   char * msg;
268
269   expiration = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
270   meta = GNUNET_CONTAINER_meta_data_create ();
271   msg = NULL;
272   ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/ns-search", &msg);
273   GNUNET_assert (NULL == msg);
274   ksk_expect_uri = GNUNET_FS_uri_dup (uri);
275   GNUNET_FS_publish_ksk (fs,
276                          ksk_uri,
277                          meta,
278                          uri,
279                          expiration,
280                          1, 1,
281                          GNUNET_FS_PUBLISH_OPTION_NONE,
282                          &publish_cont,
283                          NULL);
284   GNUNET_FS_uri_destroy (ksk_uri);
285   GNUNET_CONTAINER_meta_data_destroy (meta);
286 }
287
288
289 static void
290 adv_cont (void *cls,
291           const struct GNUNET_FS_Uri *uri,
292           const char *emsg)
293 {
294   struct GNUNET_CONTAINER_MetaData *meta;
295   struct GNUNET_FS_Namespace *ns;
296   struct GNUNET_TIME_Absolute expiration;
297
298   if (NULL != emsg)
299     {
300       fprintf (stderr, "Error publishing: %s\n", emsg);
301       err = 1;
302       GNUNET_FS_stop (fs);
303       return;
304     }
305   expiration = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
306   ns = GNUNET_FS_namespace_create (fs,
307                                    "testNamespace");
308   meta = GNUNET_CONTAINER_meta_data_create ();
309   GNUNET_assert (NULL == emsg);
310   sks_expect_uri = GNUNET_FS_uri_dup (uri);
311   GNUNET_FS_publish_sks (fs,
312                          ns,
313                          "this",
314                          "next",
315                          meta,
316                          uri, /* FIXME: this is non-sense (use CHK URI!?) */
317                          expiration,
318                          1, 1,
319                          GNUNET_FS_PUBLISH_OPTION_NONE,
320                          &sks_cont,
321                          NULL);
322   GNUNET_CONTAINER_meta_data_destroy (meta);
323   GNUNET_FS_namespace_delete (ns, GNUNET_NO);
324 }
325
326
327 static void
328 ns_iterator (void *cls,
329              const char *name,
330              const GNUNET_HashCode *id)
331 {
332   int *ok = cls;
333
334   if (0 != strcmp (name,
335                    "testNamespace"))
336     return;
337   *ok = GNUNET_YES;
338   nsid = *id;
339 }
340
341
342 static void
343 testNamespace ()
344 {
345   struct GNUNET_FS_Namespace *ns;
346   struct GNUNET_TIME_Absolute expiration;
347   struct GNUNET_CONTAINER_MetaData *meta;
348   struct GNUNET_FS_Uri *ksk_uri;
349   int ok;
350
351   ns = GNUNET_FS_namespace_create (fs,
352                                    "testNamespace");
353   ok = GNUNET_NO;
354   GNUNET_FS_namespace_list (fs, &ns_iterator, &ok);
355   if (GNUNET_NO == ok)
356     {
357       fprintf (stderr, "namespace_list failed to find namespace!\n");
358       GNUNET_FS_namespace_delete (ns, GNUNET_YES);
359       GNUNET_FS_stop (fs);
360       err = 1;
361       return;
362     }
363   expiration = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
364   meta = GNUNET_CONTAINER_meta_data_create ();
365   ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/testnsa", NULL);
366   GNUNET_FS_namespace_advertise (fs,
367                                  ksk_uri,
368                                  ns,
369                                  meta,
370                                  1, 1,
371                                  expiration,                                       
372                                  "root",
373                                  &adv_cont, NULL);
374   GNUNET_FS_uri_destroy (ksk_uri);
375   GNUNET_FS_namespace_delete (ns, GNUNET_NO);
376   GNUNET_CONTAINER_meta_data_destroy (meta);
377 }
378
379
380 static void
381 run (void *cls,
382      struct GNUNET_SCHEDULER_Handle *s,
383      char *const *args,
384      const char *cfgfile,
385      const struct GNUNET_CONFIGURATION_Handle *cfg)
386 {
387   sched = s;
388   setup_peer (&p1, "test_fs_namespace_data.conf");
389   fs = GNUNET_FS_start (sched,
390                         cfg,
391                         "test-fs-namespace",
392                         &progress_cb,
393                         NULL,
394                         GNUNET_FS_FLAGS_NONE,
395                         GNUNET_FS_OPTIONS_END);
396   testNamespace ();
397 }
398
399
400 int
401 main (int argc, char *argv[])
402 {
403   char *const argvx[] = { 
404     "test-fs-namespace",
405     "-c",
406     "test_fs_namespace_data.conf",
407 #if VERBOSE
408     "-L", "DEBUG",
409 #endif
410     NULL
411   };
412   struct GNUNET_GETOPT_CommandLineOption options[] = {
413     GNUNET_GETOPT_OPTION_END
414   };
415
416   GNUNET_log_setup ("test_fs_namespace", 
417 #if VERBOSE
418                     "DEBUG",
419 #else
420                     "WARNING",
421 #endif
422                     NULL);
423   GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1,
424                       argvx, "test-fs-namespace",
425                       "nohelp", options, &run, NULL);
426   stop_arm (&p1);
427   if (GNUNET_YES != update_started)
428     {
429       fprintf (stderr,
430                "Update search never started!\n");
431       err = 1;
432     }
433   GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-namespace/");
434   return err;
435 }
436
437
438 /* end of test_fs_namespace.c */