error handling
[oweals/gnunet.git] / src / namestore / test_namestore_api_monitoring_existing.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2013, 2018 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_monitoring_existing.c
22  * @brief testcase for zone monitoring functionality: add records first, then monitor
23  */
24 #include "platform.h"
25 #include "gnunet_namestore_service.h"
26 #include "gnunet_testing_lib.h"
27 #include "namestore.h"
28 #include "gnunet_dnsparser_lib.h"
29
30 #define TEST_RECORD_TYPE GNUNET_DNSPARSER_TYPE_TXT
31
32
33 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
34
35 static const struct GNUNET_CONFIGURATION_Handle *cfg;
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_ZoneMonitor *zm;
46
47 static int res;
48
49 static const char *s_name_1;
50
51 static struct GNUNET_GNSRECORD_Data *s_rd_1;
52
53 static const char *s_name_2;
54
55 static struct GNUNET_GNSRECORD_Data *s_rd_2;
56
57 static const char *s_name_3;
58
59 static struct GNUNET_GNSRECORD_Data *s_rd_3;
60
61 struct GNUNET_NAMESTORE_QueueEntry *ns_ops[3];
62
63
64 /**
65  * Re-establish the connection to the service.
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_break (0);
74   GNUNET_SCHEDULER_shutdown ();
75   res = 1;
76 }
77
78
79 static void
80 end (void *cls)
81 {
82   if (NULL != zm)
83   {
84     GNUNET_NAMESTORE_zone_monitor_stop (zm);
85     zm = NULL;
86   }
87   if (NULL != ns_ops[0])
88   {
89     GNUNET_NAMESTORE_cancel (ns_ops[0]);
90     ns_ops[0] = NULL;
91   }
92   if (NULL != ns_ops[1])
93   {
94     GNUNET_NAMESTORE_cancel (ns_ops[1]);
95     ns_ops[1] = NULL;
96   }
97   if (NULL != ns_ops[2])
98   {
99     GNUNET_NAMESTORE_cancel (ns_ops[2]);
100     ns_ops[2] = NULL;
101   }
102   if (NULL != endbadly_task)
103   {
104     GNUNET_SCHEDULER_cancel (endbadly_task);
105     endbadly_task = NULL;
106   }
107   if (NULL != nsh)
108   {
109     GNUNET_NAMESTORE_disconnect (nsh);
110     nsh = NULL;
111   }
112   if (NULL != s_rd_1)
113   {
114     GNUNET_free ((void *) s_rd_1->data);
115     GNUNET_free (s_rd_1);
116   }
117   if (NULL != s_rd_2)
118   {
119     GNUNET_free ((void *) s_rd_2->data);
120     GNUNET_free (s_rd_2);
121   }
122   if (NULL != s_rd_3)
123   {
124     GNUNET_free ((void *) s_rd_3->data);
125     GNUNET_free (s_rd_3);
126   }
127   if (NULL != privkey)
128   {
129     GNUNET_free (privkey);
130     privkey = NULL;
131   }
132   if (NULL != privkey2)
133   {
134     GNUNET_free (privkey2);
135     privkey2 = NULL;
136   }
137 }
138
139
140 static void
141 zone_proc (void *cls,
142            const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
143            const char *name,
144            unsigned int rd_count,
145            const struct GNUNET_GNSRECORD_Data *rd)
146 {
147   static int returned_records;
148   static int fail = GNUNET_NO;
149
150   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
151               "Comparing results name %s\n",
152               name);
153   if (0 != GNUNET_memcmp (zone_key,
154                           privkey))
155   {
156     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
157                 "Monitoring returned wrong zone key\n");
158     GNUNET_break (0);
159     GNUNET_SCHEDULER_shutdown ();
160     return;
161   }
162
163   if (0 == strcmp (name,
164                    s_name_1))
165   {
166     if (GNUNET_YES !=
167         GNUNET_GNSRECORD_records_cmp (rd,
168                                       s_rd_1))
169     {
170       GNUNET_break (0);
171       fail = GNUNET_YES;
172     }
173   }
174   else if (0 == strcmp (name,
175                         s_name_2))
176   {
177     if (GNUNET_YES !=
178         GNUNET_GNSRECORD_records_cmp (rd,
179                                       s_rd_2))
180     {
181       GNUNET_break (0);
182       fail = GNUNET_YES;
183     }
184   }
185   else
186   {
187     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
188                 "Invalid name %s\n",
189                 name);
190     GNUNET_break (0);
191     fail = GNUNET_YES;
192   }
193   GNUNET_NAMESTORE_zone_monitor_next (zm,
194                                       1);
195   if (2 == ++returned_records)
196   {
197     GNUNET_SCHEDULER_shutdown ();
198     if (GNUNET_YES == fail)
199     {
200       GNUNET_break (0);
201       res = 1;
202     }
203     else
204     {
205       res = 0;
206     }
207   }
208 }
209
210
211 static void
212 fail_cb (void *cls)
213 {
214   GNUNET_assert (0);
215 }
216
217
218 static void
219 sync_cb (void *cls)
220 {
221   /* do nothing */
222 }
223
224
225 static void
226 put_cont (void *cls,
227           int32_t success,
228           const char *emsg)
229 {
230   static int c = 0;
231   const char *label = cls;
232
233   if (0 == strcmp (label,
234                    s_name_1))
235     ns_ops[0] = NULL;
236   else if (0 == strcmp (label,
237                         s_name_2))
238     ns_ops[1] = NULL;
239   else if (0 == strcmp (label,
240                         s_name_3))
241     ns_ops[2] = NULL;
242
243   if (success == GNUNET_OK)
244   {
245     c++;
246     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
247                 "Created record %u: `%s'\n",
248                 c,
249                 label);
250   }
251   else
252   {
253     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
254                 "Failed to created records\n");
255     GNUNET_break (0);
256     res = 1;
257     GNUNET_SCHEDULER_shutdown ();
258     return;
259   }
260
261   if (3 == c)
262   {
263     /* Start monitoring */
264     zm = GNUNET_NAMESTORE_zone_monitor_start (cfg,
265                                               privkey,
266                                               GNUNET_YES,
267                                               &fail_cb,
268                                               NULL,
269                                               &zone_proc,
270                                               NULL,
271                                               &sync_cb,
272                                               NULL);
273     if (NULL == zm)
274     {
275       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
276                   "Failed to create zone monitor\n");
277       GNUNET_break (0);
278       res = 1;
279       GNUNET_SCHEDULER_shutdown ();
280       return;
281     }
282   }
283 }
284
285
286 static struct GNUNET_GNSRECORD_Data *
287 create_record (unsigned int count)
288 {
289   struct GNUNET_GNSRECORD_Data *rd;
290
291   rd = GNUNET_new_array (count,
292                          struct GNUNET_GNSRECORD_Data);
293   for (unsigned int c = 0; c < count; c++)
294   {
295     rd[c].expiration_time = GNUNET_TIME_relative_to_absolute (
296       GNUNET_TIME_UNIT_HOURS).abs_value_us;
297     rd[c].record_type = TEST_RECORD_TYPE;
298     rd[c].data_size = 50;
299     rd[c].data = GNUNET_malloc (50);
300     rd[c].flags = 0;
301     memset ((char *) rd[c].data,
302             'a',
303             50);
304   }
305   return rd;
306 }
307
308
309 static void
310 run (void *cls,
311      const struct GNUNET_CONFIGURATION_Handle *mycfg,
312      struct GNUNET_TESTING_Peer *peer)
313 {
314   res = 1;
315   privkey = GNUNET_CRYPTO_ecdsa_key_create ();
316   GNUNET_assert (NULL != privkey);
317   privkey2 = GNUNET_CRYPTO_ecdsa_key_create ();
318   GNUNET_assert (NULL != privkey2);
319
320   cfg = mycfg;
321   GNUNET_SCHEDULER_add_shutdown (&end,
322                                  NULL);
323   endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
324                                                 &endbadly,
325                                                 NULL);
326   /* Connect to namestore */
327   nsh = GNUNET_NAMESTORE_connect (cfg);
328   if (NULL == nsh)
329   {
330     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
331                 "Connect to namestore failed\n");
332     GNUNET_break (0);
333     endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly,
334                                               NULL);
335     return;
336   }
337
338   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
339               "Created record 3\n");
340   /* name in different zone */
341   s_name_3 = "dummy3";
342   s_rd_3 = create_record (1);
343   GNUNET_assert (NULL != (ns_ops[2] =
344                             GNUNET_NAMESTORE_records_store (nsh,
345                                                             privkey2,
346                                                             s_name_3,
347                                                             1,
348                                                             s_rd_3,
349                                                             &put_cont,
350                                                             (void *) s_name_3)));
351
352   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
353               "Created record 1\n");
354   s_name_1 = "dummy1";
355   s_rd_1 = create_record (1);
356   GNUNET_assert (NULL != (ns_ops[0] =
357                             GNUNET_NAMESTORE_records_store (nsh,
358                                                             privkey,
359                                                             s_name_1,
360                                                             1,
361                                                             s_rd_1,
362                                                             &put_cont,
363                                                             (void *) s_name_1)));
364   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
365               "Created record 2 \n");
366   s_name_2 = "dummy2";
367   s_rd_2 = create_record (1);
368   GNUNET_assert (NULL != (ns_ops[1] =
369                             GNUNET_NAMESTORE_records_store (nsh,
370                                                             privkey,
371                                                             s_name_2,
372                                                             1,
373                                                             s_rd_2,
374                                                             &put_cont,
375                                                             (void *) s_name_2)));
376 }
377
378
379 #include "test_common.c"
380
381
382 int
383 main (int argc,
384       char *argv[])
385 {
386   const char *plugin_name;
387   char *cfg_name;
388
389   SETUP_CFG (plugin_name, cfg_name);
390   res = 1;
391   if (0 !=
392       GNUNET_TESTING_peer_run ("test-namestore-api-monitoring-existing",
393                                cfg_name,
394                                &run,
395                                NULL))
396   {
397     GNUNET_break (0);
398     res = 1;
399   }
400   GNUNET_DISK_purge_cfg_dir (cfg_name,
401                              "GNUNET_TEST_HOME");
402   GNUNET_free (cfg_name);
403   return res;
404 }
405
406
407 /* end of test_namestore_api_monitoring_existing.c */