fix #5677
[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 != memcmp (zone_key,
154                    privkey,
155                    sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)))
156   {
157     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
158                 "Monitoring returned wrong zone key\n");
159     GNUNET_break (0);
160     GNUNET_SCHEDULER_shutdown ();
161     return;
162   }
163
164   if (0 == strcmp (name,
165                    s_name_1))
166   {
167     if (GNUNET_YES !=
168         GNUNET_GNSRECORD_records_cmp (rd,
169                                       s_rd_1))
170     {
171       GNUNET_break (0);
172       fail = GNUNET_YES;
173     }
174   }
175   else if (0 == strcmp (name,
176                         s_name_2))
177   {
178     if (GNUNET_YES !=
179         GNUNET_GNSRECORD_records_cmp (rd,
180                                       s_rd_2))
181     {
182       GNUNET_break (0);
183       fail = GNUNET_YES;
184     }
185   }
186   else
187   {
188     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
189                 "Invalid name %s\n",
190                 name);
191     GNUNET_break (0);
192     fail = GNUNET_YES;
193   }
194   GNUNET_NAMESTORE_zone_monitor_next (zm,
195                                       1);
196   if (2 == ++returned_records)
197   {
198     GNUNET_SCHEDULER_shutdown ();
199     if (GNUNET_YES == fail)
200     {
201       GNUNET_break (0);
202       res = 1;
203     }
204     else
205     {
206       res = 0;
207     }
208   }
209 }
210
211
212 static void
213 fail_cb (void *cls)
214 {
215   GNUNET_assert (0);
216 }
217
218
219 static void
220 sync_cb (void *cls)
221 {
222   /* do nothing */
223 }
224
225
226 static void
227 put_cont (void *cls,
228           int32_t success,
229           const char *emsg)
230 {
231   static int c = 0;
232   const char *label = cls;
233
234   if (0 == strcmp (label,
235                    s_name_1))
236     ns_ops[0] = NULL;
237   else if (0 == strcmp (label,
238                         s_name_2))
239     ns_ops[1] = NULL;
240   else if (0 == strcmp (label,
241                         s_name_3))
242     ns_ops[2] = NULL;
243
244   if (success == GNUNET_OK)
245   {
246     c++;
247     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
248                 "Created record %u: `%s'\n",
249                 c,
250                 label);
251   }
252   else
253   {
254     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
255                 "Failed to created records\n");
256     GNUNET_break (0);
257     res = 1;
258     GNUNET_SCHEDULER_shutdown ();
259     return;
260   }
261
262   if (3 == c)
263   {
264     /* Start monitoring */
265     zm = GNUNET_NAMESTORE_zone_monitor_start (cfg,
266                                               privkey,
267                                               GNUNET_YES,
268                                               &fail_cb,
269                                               NULL,
270                                               &zone_proc,
271                                               NULL,
272                                               &sync_cb,
273                                               NULL);
274     if (NULL == zm)
275     {
276       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
277                   "Failed to create zone monitor\n");
278       GNUNET_break (0);
279       res = 1;
280       GNUNET_SCHEDULER_shutdown ();
281       return;
282     }
283   }
284 }
285
286
287 static struct GNUNET_GNSRECORD_Data *
288 create_record (unsigned int count)
289 {
290   struct GNUNET_GNSRECORD_Data *rd;
291
292   rd = GNUNET_new_array (count,
293                          struct GNUNET_GNSRECORD_Data);
294   for (unsigned int c = 0; c < count; c++)
295   {
296     rd[c].expiration_time = GNUNET_TIME_relative_to_absolute (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 */