reduce loop counters to more practical levels
[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
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      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      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
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
29
30 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
31
32 static const struct GNUNET_CONFIGURATION_Handle *cfg;
33
34 static struct GNUNET_NAMESTORE_Handle * nsh;
35
36 static struct GNUNET_SCHEDULER_Task * endbadly_task;
37
38 static struct GNUNET_CRYPTO_EcdsaPrivateKey * privkey;
39
40 static struct GNUNET_CRYPTO_EcdsaPrivateKey * privkey2;
41
42 static struct GNUNET_NAMESTORE_ZoneMonitor *zm;
43
44 static int res;
45
46 static char * s_name_1;
47
48 static struct GNUNET_GNSRECORD_Data *s_rd_1;
49
50 static char * s_name_2;
51
52 static struct GNUNET_GNSRECORD_Data *s_rd_2;
53
54 static char * s_name_3;
55
56 static struct GNUNET_GNSRECORD_Data *s_rd_3;
57
58 struct GNUNET_NAMESTORE_QueueEntry * ns_ops[3];
59
60
61 /**
62  * Re-establish the connection to the service.
63  *
64  * @param cls handle to use to re-connect.
65  */
66 static void
67 endbadly (void *cls)
68 {
69   endbadly_task = NULL;
70   GNUNET_break (0);
71   GNUNET_SCHEDULER_shutdown ();
72   res = 1;
73 }
74
75
76 static void
77 end (void *cls)
78 {
79   if (NULL != zm)
80   {
81     GNUNET_NAMESTORE_zone_monitor_stop (zm);
82     zm = NULL;
83   }
84   if (NULL != ns_ops[0])
85   {
86     GNUNET_NAMESTORE_cancel(ns_ops[0]);
87     ns_ops[0] = NULL;
88   }
89   if (NULL != ns_ops[1])
90   {
91     GNUNET_NAMESTORE_cancel(ns_ops[1]);
92     ns_ops[1] = NULL;
93   }
94   if (NULL != ns_ops[2])
95   {
96     GNUNET_NAMESTORE_cancel(ns_ops[2]);
97     ns_ops[2] = NULL;
98   }
99   if (NULL != endbadly_task)
100   {
101     GNUNET_SCHEDULER_cancel (endbadly_task);
102     endbadly_task = NULL;
103   }
104   if (NULL != nsh)
105   {
106     GNUNET_NAMESTORE_disconnect (nsh);
107     nsh = NULL;
108   }
109
110   GNUNET_free_non_null(s_name_1);
111   GNUNET_free_non_null(s_name_2);
112   GNUNET_free_non_null(s_name_3);
113
114   if (s_rd_1 != NULL)
115   {
116     GNUNET_free ((void *)s_rd_1->data);
117     GNUNET_free (s_rd_1);
118   }
119   if (s_rd_2 != NULL)
120   {
121     GNUNET_free ((void *)s_rd_2->data);
122     GNUNET_free (s_rd_2);
123   }
124   if (s_rd_3 != NULL)
125   {
126     GNUNET_free ((void *)s_rd_3->data);
127     GNUNET_free (s_rd_3);
128   }
129
130   if (NULL != privkey)
131   {
132     GNUNET_free (privkey);
133     privkey = NULL;
134   }
135   if (NULL != privkey2)
136   {
137     GNUNET_free (privkey2);
138     privkey2 = NULL;
139   }
140 }
141
142
143 static void
144 zone_proc (void *cls,
145            const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
146            const char *name,
147            unsigned int rd_count,
148            const struct GNUNET_GNSRECORD_Data *rd)
149 {
150   static int returned_records;
151   static int fail = GNUNET_NO;
152
153   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
154               "Comparing results name %s\n",
155               name);
156
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_shutdown ();
165     return;
166   }
167
168   if (0 == strcmp (name, s_name_1))
169   {
170     if (GNUNET_YES !=
171         GNUNET_GNSRECORD_records_cmp (rd,
172                                       s_rd_1))
173     {
174       GNUNET_break (0);
175         fail = GNUNET_YES;
176     }
177   }
178   else if (0 == strcmp (name, s_name_2))
179   {
180     if (GNUNET_YES !=
181         GNUNET_GNSRECORD_records_cmp (rd,
182                                       s_rd_2))
183     {
184       GNUNET_break (0);
185         fail = GNUNET_YES;
186     }
187   }
188   else
189   {
190     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
191               "Invalid name %s\n",  name);
192         GNUNET_break (0);
193     fail = GNUNET_YES;
194   }
195   GNUNET_NAMESTORE_zone_monitor_next (zm,
196                                       1);
197   if (2 == ++returned_records)
198   {
199     GNUNET_SCHEDULER_shutdown ();
200     if (GNUNET_YES == fail)
201     {
202       GNUNET_break (0);
203       res = 1;
204     }
205     else
206     {
207       res = 0;
208     }
209   }
210 }
211
212
213 static void
214 fail_cb (void *cls)
215 {
216   GNUNET_assert (0);
217 }
218
219
220 static void
221 sync_cb (void *cls)
222 {
223   /* do nothing */
224 }
225
226
227 static void
228 put_cont (void *cls,
229           int32_t success,
230           const char *emsg)
231 {
232   static int c = 0;
233   char *label = cls;
234
235   if (0 == strcmp (label, s_name_1))
236         ns_ops[0] = NULL;
237   else if (0 == strcmp (label, s_name_2))
238         ns_ops[1] = NULL;
239   else if (0 == strcmp (label, 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 = 1111;
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 (privkey != NULL);
315
316   cfg = mycfg;
317   GNUNET_SCHEDULER_add_shutdown (&end,
318                                  NULL);
319   endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
320                                                 &endbadly,
321                                                 NULL);
322   /* Connect to namestore */
323   nsh = GNUNET_NAMESTORE_connect (cfg);
324   if (NULL == nsh)
325   {
326     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Connect to namestore\n");
327     GNUNET_break (0);
328     endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
329     return;
330   }
331
332   privkey2 = GNUNET_CRYPTO_ecdsa_key_create ();
333   GNUNET_assert (privkey2 != NULL);
334
335
336   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 3\n");
337   /* name in different zone */
338   GNUNET_asprintf(&s_name_3, "dummy3");
339   s_rd_3 = create_record(1);
340   GNUNET_assert (NULL != (ns_ops[2] =
341                           GNUNET_NAMESTORE_records_store (nsh,
342                                                           privkey2,
343                                                           s_name_3,
344                                                           1,
345                                                           s_rd_3,
346                                                           &put_cont,
347                                                           s_name_3)));
348
349   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
350               "Created record 1\n");
351   GNUNET_asprintf(&s_name_1, "dummy1");
352   s_rd_1 = create_record(1);
353   GNUNET_assert (NULL != (ns_ops[0] =
354                           GNUNET_NAMESTORE_records_store(nsh,
355                                                          privkey,
356                                                          s_name_1,
357                                                          1,
358                                                          s_rd_1,
359                                                          &put_cont,
360                                                          s_name_1)));
361   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
362               "Created record 2 \n");
363   GNUNET_asprintf(&s_name_2, "dummy2");
364   s_rd_2 = create_record(1);
365   GNUNET_assert (NULL != (ns_ops[1] =
366                           GNUNET_NAMESTORE_records_store (nsh,
367                                                           privkey,
368                                                           s_name_2,
369                                                           1,
370                                                           s_rd_2,
371                                                           &put_cont,
372                                                           s_name_2)));
373 }
374
375
376 int
377 main (int argc, char *argv[])
378 {
379   const char *plugin_name;
380   char *cfg_name;
381
382   plugin_name = GNUNET_TESTING_get_testname_from_underscore (argv[0]);
383   GNUNET_asprintf (&cfg_name,
384                    "test_namestore_api_%s.conf",
385                    plugin_name);
386   res = 1;
387   GNUNET_DISK_purge_cfg_dir (cfg_name,
388                              "GNUNET_TEST_HOME");
389   if (0 !=
390       GNUNET_TESTING_peer_run ("test-namestore-api-monitoring-existing",
391                                cfg_name,
392                                &run,
393                                NULL))
394   {
395     res = 1;
396   }
397   GNUNET_DISK_purge_cfg_dir (cfg_name,
398                              "GNUNET_TEST_HOME");
399   GNUNET_free (cfg_name);
400   return res;
401 }
402
403
404 /* end of test_namestore_api_monitoring_existing.c */