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