splitting 'struct GNUNET_CRYPTO_EccPublicKey' into one struct for signing and another...
[oweals/gnunet.git] / src / fs / test_fs_namespace.c
1 /*
2      This file is part of GNUnet.
3      (C) 2005-2013 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 fs/test_fs_namespace.c
23  * @brief Test for fs_namespace.c
24  * @author Christian Grothoff
25  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet_testing_lib.h"
29 #include "gnunet_fs_service.h"
30
31
32 static struct GNUNET_CRYPTO_EccPublicSignKey nsid;
33
34 static struct GNUNET_FS_Uri *sks_expect_uri;
35
36 static struct GNUNET_FS_Uri *ksk_expect_uri;
37
38 static struct GNUNET_FS_Handle *fs;
39
40 static struct GNUNET_FS_SearchContext *sks_search;
41
42 static struct GNUNET_FS_SearchContext *ksk_search;
43
44 static GNUNET_SCHEDULER_TaskIdentifier kill_task;
45
46 static int update_started;
47
48 static int err;
49
50
51 static void
52 abort_ksk_search_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
53 {
54   if (ksk_search != NULL)
55   {
56     GNUNET_FS_search_stop (ksk_search);
57     ksk_search = NULL;
58     if (sks_search == NULL)
59     {
60       GNUNET_FS_stop (fs);
61       if (GNUNET_SCHEDULER_NO_TASK != kill_task)
62         GNUNET_SCHEDULER_cancel (kill_task);
63     }
64   }
65 }
66
67
68 static void
69 abort_sks_search_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
70 {
71   if (sks_search == NULL)
72     return;
73   GNUNET_FS_search_stop (sks_search);
74   sks_search = NULL;
75   if (ksk_search == NULL)
76   {
77     GNUNET_FS_stop (fs);
78     if (GNUNET_SCHEDULER_NO_TASK != kill_task)
79       GNUNET_SCHEDULER_cancel (kill_task);
80   }
81 }
82
83
84 static void
85 do_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
86 {
87   err = 1;
88   FPRINTF (stderr, "%s",  "Operation timed out\n");
89   kill_task = GNUNET_SCHEDULER_NO_TASK;
90   abort_sks_search_task (NULL, tc);
91   abort_ksk_search_task (NULL, tc);
92 }
93
94
95 static void *
96 progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event)
97 {
98   switch (event->status)
99   {
100   case GNUNET_FS_STATUS_SEARCH_RESULT:
101     if (sks_search == event->value.search.sc)
102     {
103       if (!GNUNET_FS_uri_test_equal
104           (sks_expect_uri, event->value.search.specifics.result.uri))
105       {
106         FPRINTF (stderr, "%s",  "Wrong result for sks search!\n");
107         err = 1;
108       }
109       /* give system 1ms to initiate update search! */
110       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS,
111                                     &abort_sks_search_task, NULL);
112     }
113     else if (ksk_search == event->value.search.sc)
114     {
115       if (!GNUNET_FS_uri_test_equal
116           (ksk_expect_uri, event->value.search.specifics.result.uri))
117       {
118         FPRINTF (stderr, "%s",  "Wrong result for ksk search!\n");
119         err = 1;
120       }
121       GNUNET_SCHEDULER_add_continuation (&abort_ksk_search_task, NULL,
122                                          GNUNET_SCHEDULER_REASON_PREREQ_DONE);
123     }
124     else
125     {
126       FPRINTF (stderr, "%s",  "Unexpected search result received!\n");
127       GNUNET_break (0);
128     }
129     break;
130   case GNUNET_FS_STATUS_SEARCH_ERROR:
131     FPRINTF (stderr, "Error searching file: %s\n",
132              event->value.search.specifics.error.message);
133     if (sks_search == event->value.search.sc)
134       GNUNET_SCHEDULER_add_continuation (&abort_sks_search_task, NULL,
135                                          GNUNET_SCHEDULER_REASON_PREREQ_DONE);
136     else if (ksk_search == event->value.search.sc)
137       GNUNET_SCHEDULER_add_continuation (&abort_ksk_search_task, NULL,
138                                          GNUNET_SCHEDULER_REASON_PREREQ_DONE);
139     else
140       GNUNET_break (0);
141     break;
142   case GNUNET_FS_STATUS_SEARCH_START:
143     GNUNET_assert ((NULL == event->value.search.cctx) ||
144                    (0 == strcmp ("sks_search", event->value.search.cctx)) ||
145                    (0 == strcmp ("ksk_search", event->value.search.cctx)));
146     if (NULL == event->value.search.cctx)
147     {
148       GNUNET_assert (0 == strcmp ("sks_search", event->value.search.pctx));
149       update_started = GNUNET_YES;
150     }
151     GNUNET_assert (1 == event->value.search.anonymity);
152     break;
153   case GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED:
154     return NULL;
155   case GNUNET_FS_STATUS_SEARCH_STOPPED:
156     return NULL;
157   default:
158     FPRINTF (stderr, "Unexpected event: %d\n", event->status);
159     break;
160   }
161   return event->value.search.cctx;
162 }
163
164
165 static void
166 publish_cont (void *cls, const struct GNUNET_FS_Uri *ksk_uri, const char *emsg)
167 {
168   char *msg;
169   struct GNUNET_FS_Uri *sks_uri;
170   char sbuf[1024];
171   char buf[1024];
172   char *ret;
173
174   if (NULL != emsg)
175   {
176     FPRINTF (stderr, "Error publishing: %s\n", emsg);
177     err = 1;
178     GNUNET_FS_stop (fs);
179     return;
180   }
181   ret = GNUNET_STRINGS_data_to_string (&nsid, sizeof (nsid), buf, sizeof (buf));
182   GNUNET_assert (NULL != ret);
183   ret[0] = '\0';
184   GNUNET_snprintf (sbuf, sizeof (sbuf), "gnunet://fs/sks/%s/this", buf);
185   sks_uri = GNUNET_FS_uri_parse (sbuf, &msg);
186   if (NULL == sks_uri)
187   {
188     FPRINTF (stderr, "failed to parse URI `%s': %s\n", sbuf, msg);
189     err = 1;
190     GNUNET_FS_stop (fs);
191     GNUNET_free_non_null (msg);
192     return;
193   }
194   ksk_search =
195       GNUNET_FS_search_start (fs, ksk_uri, 1, GNUNET_FS_SEARCH_OPTION_NONE,
196                               "ksk_search");
197   sks_search =
198       GNUNET_FS_search_start (fs, sks_uri, 1, GNUNET_FS_SEARCH_OPTION_NONE,
199                               "sks_search");
200   GNUNET_FS_uri_destroy (sks_uri);
201 }
202
203
204 static void
205 sks_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg)
206 {
207   struct GNUNET_CONTAINER_MetaData *meta;
208   struct GNUNET_FS_Uri *ksk_uri;
209   char *msg;
210   struct GNUNET_FS_BlockOptions bo;
211
212   if (NULL == uri)
213   {
214     fprintf (stderr, "Error publishing: %s\n", emsg);
215     err = 1;
216     GNUNET_FS_stop (fs);
217     return;
218   }
219   meta = GNUNET_CONTAINER_meta_data_create ();
220   msg = NULL;
221   ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/ns-search", &msg);
222   GNUNET_assert (NULL == msg);
223   ksk_expect_uri = GNUNET_FS_uri_dup (uri);
224   bo.content_priority = 1;
225   bo.anonymity_level = 1;
226   bo.replication_level = 0;
227   bo.expiration_time =
228       GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
229   GNUNET_FS_publish_ksk (fs, ksk_uri, meta, uri, &bo,
230                          GNUNET_FS_PUBLISH_OPTION_NONE, &publish_cont, NULL);
231   GNUNET_FS_uri_destroy (ksk_uri);
232   GNUNET_CONTAINER_meta_data_destroy (meta);
233 }
234
235
236 static void
237 adv_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg)
238 {
239   struct GNUNET_CONTAINER_MetaData *meta;
240   struct GNUNET_CRYPTO_EccPrivateKey *ns;
241   struct GNUNET_FS_BlockOptions bo;
242
243   if (NULL != emsg)
244   {
245     FPRINTF (stderr, "Error publishing: %s\n", emsg);
246     err = 1;
247     GNUNET_FS_stop (fs);
248     return;
249   }
250   ns = GNUNET_CRYPTO_ecc_key_create ();
251   meta = GNUNET_CONTAINER_meta_data_create ();
252   sks_expect_uri = GNUNET_FS_uri_dup (uri);
253   bo.content_priority = 1;
254   bo.anonymity_level = 1;
255   bo.replication_level = 0;
256   bo.expiration_time =
257       GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
258   GNUNET_CRYPTO_ecc_key_get_public_for_signature (ns, &nsid);
259   GNUNET_FS_publish_sks (fs, ns, "this", "next", meta, uri,
260                          &bo, GNUNET_FS_PUBLISH_OPTION_NONE, &sks_cont, NULL);
261   GNUNET_CONTAINER_meta_data_destroy (meta);
262   GNUNET_free (ns);
263 }
264
265
266 static void
267 testNamespace ()
268 {
269   struct GNUNET_CRYPTO_EccPrivateKey *ns;
270   struct GNUNET_FS_BlockOptions bo;
271   struct GNUNET_CONTAINER_MetaData *meta;
272   struct GNUNET_FS_Uri *ksk_uri;
273   struct GNUNET_FS_Uri *sks_uri;
274
275   ns = GNUNET_CRYPTO_ecc_key_create ();
276   meta = GNUNET_CONTAINER_meta_data_create ();
277   ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/testnsa", NULL);
278   bo.content_priority = 1;
279   bo.anonymity_level = 1;
280   bo.replication_level = 0;
281   bo.expiration_time =
282       GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
283   sks_uri = GNUNET_FS_uri_sks_create (&nsid, "root");
284   GNUNET_FS_publish_ksk (fs, 
285                          ksk_uri, meta, sks_uri, 
286                          &bo, GNUNET_FS_PUBLISH_OPTION_NONE,
287                          &adv_cont, NULL);
288   GNUNET_FS_uri_destroy (sks_uri);
289   kill_task =
290       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, &do_timeout,
291                                     NULL);
292   GNUNET_FS_uri_destroy (ksk_uri);
293   GNUNET_CONTAINER_meta_data_destroy (meta);
294   GNUNET_free (ns);
295 }
296
297
298 static void
299 run (void *cls, 
300      const struct GNUNET_CONFIGURATION_Handle *cfg,
301      struct GNUNET_TESTING_Peer *peer)
302 {
303   fs = GNUNET_FS_start (cfg, "test-fs-namespace", &progress_cb, NULL,
304                         GNUNET_FS_FLAGS_NONE, GNUNET_FS_OPTIONS_END);
305   testNamespace ();
306 }
307
308
309 int
310 main (int argc, char *argv[])
311 {
312   if (0 != GNUNET_TESTING_peer_run ("test-fs-namespace",
313                                     "test_fs_namespace_data.conf",
314                                     &run, NULL))
315     return 1;
316   return err;
317 }
318
319
320 /* end of test_fs_namespace.c */