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