deprecate ill-defined set_nick API
[oweals/gnunet.git] / src / namestore / test_namestore_api_zone_iteration_nick.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 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  * @file namestore/test_namestore_api_zone_iteration.c
22  * @brief testcase for zone iteration functionality: iterate all zones
23  */
24 #include "platform.h"
25 #include "gnunet_namestore_service.h"
26 #include "gnunet_gns_service.h"
27 #include "gnunet_testing_lib.h"
28 #include "namestore.h"
29 #include "gnunet_dnsparser_lib.h"
30
31 #define TEST_RECORD_TYPE GNUNET_DNSPARSER_TYPE_TXT
32
33 #define ZONE_NICK_1 "nick1"
34 #define ZONE_NICK_2 "nick2"
35
36 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 100)
37
38
39 static struct GNUNET_NAMESTORE_Handle *nsh;
40
41 static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey;
42
43 static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey2;
44
45 static struct GNUNET_NAMESTORE_ZoneIterator *zi;
46
47 static int res;
48
49 static int returned_records;
50
51 static char *s_name_1;
52
53 static struct GNUNET_GNSRECORD_Data *s_rd_1;
54
55 static char *s_name_2;
56
57 static struct GNUNET_GNSRECORD_Data *s_rd_2;
58
59 static char *s_name_3;
60
61 static struct GNUNET_GNSRECORD_Data *s_rd_3;
62
63 static struct GNUNET_NAMESTORE_QueueEntry *nsqe;
64
65
66 /**
67  * Re-establish the connection to the service.
68  *
69  * @param cls handle to use to re-connect.
70  * @param tc scheduler context
71  */
72 static void
73 end (void *cls)
74 {
75   if (NULL != zi)
76   {
77     GNUNET_NAMESTORE_zone_iteration_stop (zi);
78     zi = NULL;
79   }
80   if (nsh != NULL)
81   {
82     GNUNET_NAMESTORE_disconnect (nsh);
83     nsh = NULL;
84   }
85   GNUNET_free_non_null (s_name_1);
86   GNUNET_free_non_null (s_name_2);
87   GNUNET_free_non_null (s_name_3);
88
89   if (s_rd_1 != NULL)
90   {
91     GNUNET_free_nz ((void *) s_rd_1->data);
92     GNUNET_free (s_rd_1);
93   }
94   if (s_rd_2 != NULL)
95   {
96     GNUNET_free_nz ((void *) s_rd_2->data);
97     GNUNET_free (s_rd_2);
98   }
99   if (s_rd_3 != NULL)
100   {
101     GNUNET_free_nz ((void *) s_rd_3->data);
102     GNUNET_free (s_rd_3);
103   }
104 }
105
106
107 static int
108 check_zone_1 (const char *label, unsigned int rd_count,
109               const struct GNUNET_GNSRECORD_Data *rd)
110 {
111   for (unsigned int c = 0; c < rd_count; c++)
112   {
113     if ((rd[c].record_type == GNUNET_GNSRECORD_TYPE_NICK) &&
114         (0 != strcmp (rd[c].data, ZONE_NICK_1)))
115     {
116       GNUNET_break (0);
117       return GNUNET_YES;
118     }
119   }
120   return GNUNET_NO;
121 }
122
123
124 static int
125 check_zone_2 (const char *label,
126               unsigned int rd_count,
127               const struct GNUNET_GNSRECORD_Data *rd)
128 {
129   for (unsigned int c = 0; c < rd_count; c++)
130   {
131     if ((rd[c].record_type == GNUNET_GNSRECORD_TYPE_NICK) &&
132         (0 != strcmp (rd[c].data, ZONE_NICK_2)))
133     {
134       GNUNET_break (0);
135       return GNUNET_YES;
136     }
137   }
138   return GNUNET_NO;
139 }
140
141
142 static void
143 zone_proc_end (void *cls)
144 {
145   zi = NULL;
146   res = 0;
147   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
148               "Received last result, iteration done after receing %u results\n",
149               returned_records);
150   GNUNET_SCHEDULER_shutdown ();
151 }
152
153
154 static void
155 zone_proc (void *cls,
156            const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
157            const char *label,
158            unsigned int rd_count,
159            const struct GNUNET_GNSRECORD_Data *rd)
160 {
161   int failed = GNUNET_NO;
162
163   GNUNET_assert (NULL != zone);
164   if (0 == GNUNET_memcmp (zone, &privkey))
165   {
166     failed = check_zone_1 (label, rd_count, rd);
167     if (GNUNET_YES == failed)
168       GNUNET_break (0);
169   }
170   else if (0 == GNUNET_memcmp (zone, &privkey2))
171   {
172     failed = check_zone_2 (label, rd_count, rd);
173     if (GNUNET_YES == failed)
174       GNUNET_break (0);
175   }
176   else
177   {
178     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
179                 "Received invalid zone\n");
180     failed = GNUNET_YES;
181     GNUNET_break (0);
182   }
183
184   if (failed == GNUNET_NO)
185   {
186     returned_records++;
187     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
188                 "Telling namestore to send the next result\n");
189     GNUNET_NAMESTORE_zone_iterator_next (zi,
190                                          1);
191   }
192   else
193   {
194     GNUNET_break (0);
195     res = 1;
196     GNUNET_SCHEDULER_shutdown ();
197   }
198 }
199
200
201 static void
202 fail_cb (void *cls)
203 {
204   GNUNET_assert (0);
205 }
206
207
208 static void
209 put_cont (void *cls,
210           int32_t success,
211           const char *emsg)
212 {
213   static int c = 0;
214
215   if (success == GNUNET_OK)
216   {
217     c++;
218     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record %u \n", c);
219   }
220   else
221   {
222     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to created records: `%s'\n",
223                 emsg);
224     GNUNET_break (0);
225     GNUNET_SCHEDULER_shutdown ();
226     return;
227   }
228
229   if (c == 3)
230   {
231     res = 1;
232     returned_records = 0;
233     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
234                 "All records created, starting iteration over all zones \n");
235     zi = GNUNET_NAMESTORE_zone_iteration_start (nsh,
236                                                 NULL,
237                                                 &fail_cb,
238                                                 NULL,
239                                                 &zone_proc,
240                                                 NULL,
241                                                 &zone_proc_end,
242                                                 NULL);
243     if (zi == NULL)
244     {
245       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to create zone iterator\n");
246       GNUNET_break (0);
247       GNUNET_SCHEDULER_shutdown ();
248       return;
249     }
250   }
251 }
252
253
254 static struct GNUNET_GNSRECORD_Data *
255 create_record (unsigned int count)
256 {
257   struct GNUNET_GNSRECORD_Data *rd;
258
259   rd = GNUNET_new_array (count,
260                          struct GNUNET_GNSRECORD_Data);
261   for (unsigned int c = 0; c < count; c++)
262   {
263     rd[c].expiration_time = GNUNET_TIME_relative_to_absolute (
264       GNUNET_TIME_UNIT_HOURS).abs_value_us;
265     rd[c].record_type = TEST_RECORD_TYPE;
266     rd[c].data_size = 50;
267     rd[c].data = GNUNET_malloc (50);
268     rd[c].flags = 0;
269     memset ((char *) rd[c].data, 'a', 50);
270   }
271   return rd;
272 }
273
274
275 static void
276 nick_2_cont (void *cls,
277              int32_t success,
278              const char *emsg)
279 {
280   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
281               "Nick added : %s\n",
282               (success == GNUNET_OK) ? "SUCCESS" : "FAIL");
283
284   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 1\n");
285
286   GNUNET_asprintf (&s_name_1, "dummy1");
287   s_rd_1 = create_record (1);
288   GNUNET_NAMESTORE_records_store (nsh, &privkey, s_name_1,
289                                   1, s_rd_1,
290                                   &put_cont, NULL);
291
292   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
293               "Created record 2 \n");
294   GNUNET_asprintf (&s_name_2, "dummy2");
295   s_rd_2 = create_record (1);
296   GNUNET_NAMESTORE_records_store (nsh, &privkey, s_name_2,
297                                   1, s_rd_2, &put_cont, NULL);
298
299   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
300               "Created record 3\n");
301
302   /* name in different zone */
303   GNUNET_asprintf (&s_name_3, "dummy3");
304   s_rd_3 = create_record (1);
305   GNUNET_NAMESTORE_records_store (nsh, &privkey2, s_name_3,
306                                   1, s_rd_3,
307                                   &put_cont, NULL);
308 }
309
310
311 static void
312 nick_1_cont (void *cls, int32_t success, const char *emsg)
313 {
314   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
315               "Nick 1 added : %s\n",
316               (success == GNUNET_OK) ? "SUCCESS" : "FAIL");
317   struct GNUNET_GNSRECORD_Data rd;
318
319   memset (&rd, 0, sizeof(rd));
320   rd.data = ZONE_NICK_2;
321   rd.data_size = strlen (ZONE_NICK_2) + 1;
322   rd.record_type = GNUNET_GNSRECORD_TYPE_NICK;
323   rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
324   rd.flags |= GNUNET_GNSRECORD_RF_PRIVATE;
325   nsqe = GNUNET_NAMESTORE_records_store (nsh,
326                                          &privkey2,
327                                          GNUNET_GNS_EMPTY_LABEL_AT,
328                                          1,
329                                          &rd,
330                                          &nick_2_cont,
331                                          &privkey2);
332
333   if (NULL == nsqe)
334   {
335     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
336                 _ ("Namestore cannot store no block\n"));
337   }
338 }
339
340
341 /**
342  * Callback called from the zone iterator when we iterate over
343  * the empty zone.  Check that we got no records and then
344  * start the actual tests by filling the zone.
345  */
346 static void
347 empty_zone_proc (void *cls,
348                  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
349                  const char *label,
350                  unsigned int rd_count,
351                  const struct GNUNET_GNSRECORD_Data *rd)
352 {
353   GNUNET_assert (nsh == cls);
354
355   if (NULL != zone)
356   {
357     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
358                 _ ("Expected empty zone but received zone private key\n"));
359     GNUNET_break (0);
360     GNUNET_SCHEDULER_shutdown ();
361     return;
362   }
363   if ((NULL != label) || (NULL != rd) || (0 != rd_count))
364   {
365     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
366                 _ ("Expected no zone content but received data\n"));
367     GNUNET_break (0);
368     GNUNET_SCHEDULER_shutdown ();
369     return;
370   }
371   GNUNET_assert (0);
372 }
373
374
375 static void
376 empty_zone_end (void *cls)
377 {
378   GNUNET_assert (nsh == cls);
379   struct GNUNET_GNSRECORD_Data rd;
380
381   zi = NULL;
382   GNUNET_CRYPTO_ecdsa_key_create (&privkey);
383   GNUNET_CRYPTO_ecdsa_key_create (&privkey2);
384
385   memset (&rd, 0, sizeof(rd));
386   rd.data = ZONE_NICK_1;
387   rd.data_size = strlen (ZONE_NICK_1) + 1;
388   rd.record_type = GNUNET_GNSRECORD_TYPE_NICK;
389   rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
390   rd.flags |= GNUNET_GNSRECORD_RF_PRIVATE;
391   nsqe = GNUNET_NAMESTORE_records_store (nsh,
392                                          &privkey,
393                                          GNUNET_GNS_EMPTY_LABEL_AT,
394                                          1,
395                                          &rd,
396                                          &nick_1_cont,
397                                          NULL);
398   if (NULL == nsqe)
399   {
400     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
401                 _ ("Namestore cannot store no block\n"));
402   }
403 }
404
405
406 static void
407 run (void *cls,
408      const struct GNUNET_CONFIGURATION_Handle *cfg,
409      struct GNUNET_TESTING_Peer *peer)
410 {
411   nsh = GNUNET_NAMESTORE_connect (cfg);
412   GNUNET_break (NULL != nsh);
413   GNUNET_SCHEDULER_add_shutdown (&end,
414                                  NULL);
415   /* first, iterate over empty namestore */
416   zi = GNUNET_NAMESTORE_zone_iteration_start (nsh,
417                                               NULL,
418                                               &fail_cb,
419                                               NULL,
420                                               &empty_zone_proc,
421                                               nsh,
422                                               &empty_zone_end,
423                                               nsh);
424   if (NULL == zi)
425   {
426     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
427                 "Failed to create zone iterator\n");
428     GNUNET_break (0);
429     GNUNET_SCHEDULER_shutdown ();
430   }
431 }
432
433
434 #include "test_common.c"
435
436
437 int
438 main (int argc, char *argv[])
439 {
440   const char *plugin_name;
441   char *cfg_name;
442
443   SETUP_CFG (plugin_name, cfg_name);
444   res = 1;
445   if (0 !=
446       GNUNET_TESTING_peer_run ("test-namestore-api-zone-iteration-nick",
447                                cfg_name,
448                                &run,
449                                NULL))
450   {
451     res = 1;
452   }
453   GNUNET_DISK_purge_cfg_dir (cfg_name,
454                              "GNUNET_TEST_HOME");
455   GNUNET_free (cfg_name);
456   return res;
457 }
458
459
460 /* end of test_namestore_api_zone_iteration.c */