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