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