error handling
[oweals/gnunet.git] / src / fs / test_fs_namespace.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2005-2013 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your 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      Affero General Public License for more details.
14
15      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
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_EcdsaPublicKey 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 struct GNUNET_SCHEDULER_Task *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)
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 (NULL != kill_task)
62         GNUNET_SCHEDULER_cancel (kill_task);
63     }
64   }
65 }
66
67
68 static void
69 abort_sks_search_task (void *cls)
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 (NULL != kill_task)
79       GNUNET_SCHEDULER_cancel (kill_task);
80   }
81 }
82
83
84 static void
85 do_timeout (void *cls)
86 {
87   err = 1;
88   fprintf (stderr, "%s", "Operation timed out\n");
89   kill_task = NULL;
90   abort_sks_search_task (NULL);
91   abort_ksk_search_task (NULL);
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_now (&abort_ksk_search_task, NULL);
122     }
123     else
124     {
125       fprintf (stderr, "%s", "Unexpected search result received!\n");
126       GNUNET_break (0);
127     }
128     break;
129
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_now (&abort_sks_search_task, NULL);
135     else if (ksk_search == event->value.search.sc)
136       GNUNET_SCHEDULER_add_now (&abort_ksk_search_task, NULL);
137     else
138       GNUNET_break (0);
139     break;
140
141   case GNUNET_FS_STATUS_SEARCH_START:
142     GNUNET_assert ((NULL == event->value.search.cctx) ||
143                    (0 == strcmp ("sks_search", event->value.search.cctx)) ||
144                    (0 == strcmp ("ksk_search", event->value.search.cctx)));
145     if (NULL == event->value.search.cctx)
146     {
147       GNUNET_assert (0 == strcmp ("sks_search", event->value.search.pctx));
148       update_started = GNUNET_YES;
149     }
150     GNUNET_assert (1 == event->value.search.anonymity);
151     break;
152
153   case GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED:
154     return NULL;
155
156   case GNUNET_FS_STATUS_SEARCH_STOPPED:
157     return NULL;
158
159   default:
160     fprintf (stderr, "Unexpected event: %d\n", event->status);
161     break;
162   }
163   return event->value.search.cctx;
164 }
165
166
167 static void
168 publish_cont (void *cls, const struct GNUNET_FS_Uri *ksk_uri, const char *emsg)
169 {
170   char *msg;
171   struct GNUNET_FS_Uri *sks_uri;
172   char sbuf[1024];
173   char buf[1024];
174   char *ret;
175
176   if (NULL != emsg)
177   {
178     fprintf (stderr, "Error publishing: %s\n", emsg);
179     err = 1;
180     GNUNET_FS_stop (fs);
181     return;
182   }
183   ret = GNUNET_STRINGS_data_to_string (&nsid, sizeof(nsid), buf, sizeof(buf));
184   GNUNET_assert (NULL != ret);
185   ret[0] = '\0';
186   GNUNET_snprintf (sbuf, sizeof(sbuf), "gnunet://fs/sks/%s/this", buf);
187   sks_uri = GNUNET_FS_uri_parse (sbuf, &msg);
188   if (NULL == sks_uri)
189   {
190     fprintf (stderr, "failed to parse URI `%s': %s\n", sbuf, msg);
191     err = 1;
192     GNUNET_FS_stop (fs);
193     GNUNET_free_non_null (msg);
194     return;
195   }
196   ksk_search =
197     GNUNET_FS_search_start (fs, ksk_uri, 1, GNUNET_FS_SEARCH_OPTION_NONE,
198                             "ksk_search");
199   sks_search =
200     GNUNET_FS_search_start (fs, sks_uri, 1, GNUNET_FS_SEARCH_OPTION_NONE,
201                             "sks_search");
202   GNUNET_FS_uri_destroy (sks_uri);
203 }
204
205
206 static void
207 sks_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg)
208 {
209   struct GNUNET_CONTAINER_MetaData *meta;
210   struct GNUNET_FS_Uri *ksk_uri;
211   char *msg;
212   struct GNUNET_FS_BlockOptions bo;
213
214   if (NULL == uri)
215   {
216     fprintf (stderr, "Error publishing: %s\n", emsg);
217     err = 1;
218     GNUNET_FS_stop (fs);
219     return;
220   }
221   meta = GNUNET_CONTAINER_meta_data_create ();
222   msg = NULL;
223   ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/ns-search", &msg);
224   GNUNET_assert (NULL == msg);
225   ksk_expect_uri = GNUNET_FS_uri_dup (uri);
226   bo.content_priority = 1;
227   bo.anonymity_level = 1;
228   bo.replication_level = 0;
229   bo.expiration_time =
230     GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
231   GNUNET_FS_publish_ksk (fs, ksk_uri, meta, uri, &bo,
232                          GNUNET_FS_PUBLISH_OPTION_NONE, &publish_cont, NULL);
233   GNUNET_FS_uri_destroy (ksk_uri);
234   GNUNET_CONTAINER_meta_data_destroy (meta);
235 }
236
237
238 static void
239 adv_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg)
240 {
241   struct GNUNET_CONTAINER_MetaData *meta;
242   struct GNUNET_CRYPTO_EcdsaPrivateKey *ns;
243   struct GNUNET_FS_BlockOptions bo;
244
245   if (NULL != emsg)
246   {
247     fprintf (stderr, "Error publishing: %s\n", emsg);
248     err = 1;
249     GNUNET_FS_stop (fs);
250     return;
251   }
252   ns = GNUNET_CRYPTO_ecdsa_key_create ();
253   meta = GNUNET_CONTAINER_meta_data_create ();
254   sks_expect_uri = GNUNET_FS_uri_dup (uri);
255   bo.content_priority = 1;
256   bo.anonymity_level = 1;
257   bo.replication_level = 0;
258   bo.expiration_time =
259     GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
260   GNUNET_CRYPTO_ecdsa_key_get_public (ns, &nsid);
261   GNUNET_FS_publish_sks (fs, ns, "this", "next", meta, uri,
262                          &bo, GNUNET_FS_PUBLISH_OPTION_NONE, &sks_cont, NULL);
263   GNUNET_CONTAINER_meta_data_destroy (meta);
264   GNUNET_free (ns);
265 }
266
267
268 static void
269 testNamespace ()
270 {
271   struct GNUNET_CRYPTO_EcdsaPrivateKey *ns;
272   struct GNUNET_FS_BlockOptions bo;
273   struct GNUNET_CONTAINER_MetaData *meta;
274   struct GNUNET_FS_Uri *ksk_uri;
275   struct GNUNET_FS_Uri *sks_uri;
276
277   ns = GNUNET_CRYPTO_ecdsa_key_create ();
278   meta = GNUNET_CONTAINER_meta_data_create ();
279   ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/testnsa", NULL);
280   bo.content_priority = 1;
281   bo.anonymity_level = 1;
282   bo.replication_level = 0;
283   bo.expiration_time =
284     GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
285   sks_uri = GNUNET_FS_uri_sks_create (&nsid, "root");
286   GNUNET_FS_publish_ksk (fs,
287                          ksk_uri, meta, sks_uri,
288                          &bo, GNUNET_FS_PUBLISH_OPTION_NONE,
289                          &adv_cont, NULL);
290   GNUNET_FS_uri_destroy (sks_uri);
291   kill_task =
292     GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, &do_timeout,
293                                   NULL);
294   GNUNET_FS_uri_destroy (ksk_uri);
295   GNUNET_CONTAINER_meta_data_destroy (meta);
296   GNUNET_free (ns);
297 }
298
299
300 static void
301 run (void *cls,
302      const struct GNUNET_CONFIGURATION_Handle *cfg,
303      struct GNUNET_TESTING_Peer *peer)
304 {
305   fs = GNUNET_FS_start (cfg, "test-fs-namespace", &progress_cb, NULL,
306                         GNUNET_FS_FLAGS_NONE, GNUNET_FS_OPTIONS_END);
307   testNamespace ();
308 }
309
310
311 int
312 main (int argc, char *argv[])
313 {
314   if (0 != GNUNET_TESTING_peer_run ("test-fs-namespace",
315                                     "test_fs_namespace_data.conf",
316                                     &run, NULL))
317     return 1;
318   return err;
319 }
320
321
322 /* end of test_fs_namespace.c */