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