-fixed _clear() in peers "helper"
[oweals/gnunet.git] / src / namestore / test_namestore_api_monitoring.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2013 Christian Grothoff (and other contributing authors)
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.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
29
30 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 100)
31
32
33 static struct GNUNET_NAMESTORE_Handle * nsh;
34
35 static struct GNUNET_SCHEDULER_Task * endbadly_task;
36
37 static struct GNUNET_CRYPTO_EcdsaPrivateKey * privkey;
38
39 static struct GNUNET_CRYPTO_EcdsaPrivateKey * privkey2;
40
41 static struct GNUNET_NAMESTORE_ZoneMonitor *zm;
42
43 static int res;
44
45 static char * s_name_1;
46
47 static struct GNUNET_GNSRECORD_Data *s_rd_1;
48
49 static char * s_name_2;
50
51 static struct GNUNET_GNSRECORD_Data *s_rd_2;
52
53 static char * s_name_3;
54
55 static struct GNUNET_GNSRECORD_Data *s_rd_3;
56
57 struct GNUNET_NAMESTORE_QueueEntry * ns_ops[3];
58
59 static char *directory;
60
61 static void
62 do_shutdown ()
63 {
64   if (NULL != zm)
65   {
66     GNUNET_NAMESTORE_zone_monitor_stop (zm);
67     zm = NULL;
68   }
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
86   if (NULL != nsh)
87   {
88     GNUNET_NAMESTORE_disconnect (nsh);
89     nsh = NULL;
90   }
91
92   GNUNET_free_non_null(s_name_1);
93   GNUNET_free_non_null(s_name_2);
94   GNUNET_free_non_null(s_name_3);
95
96   if (s_rd_1 != NULL)
97   {
98     GNUNET_free ((void *)s_rd_1->data);
99     GNUNET_free (s_rd_1);
100   }
101   if (s_rd_2 != NULL)
102   {
103     GNUNET_free ((void *)s_rd_2->data);
104     GNUNET_free (s_rd_2);
105   }
106   if (s_rd_3 != NULL)
107   {
108     GNUNET_free ((void *)s_rd_3->data);
109     GNUNET_free (s_rd_3);
110   }
111
112   if (NULL != privkey)
113   {
114     GNUNET_free (privkey);
115     privkey = NULL;
116   }
117   if (NULL != privkey2)
118   {
119     GNUNET_free (privkey2);
120     privkey2 = NULL;
121   }
122 }
123
124
125 /**
126  * Re-establish the connection to the service.
127  *
128  * @param cls handle to use to re-connect.
129  * @param tc scheduler context
130  */
131 static void
132 endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
133 {
134   do_shutdown ();
135   res = 1;
136 }
137
138
139 static void
140 end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
141 {
142   do_shutdown ();
143   res = 0;
144 }
145
146
147 static void
148 zone_proc (void *cls,
149            const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
150            const char *name,
151            unsigned int rd_count,
152            const struct GNUNET_GNSRECORD_Data *rd)
153 {
154   static int returned_records;
155   static int fail = GNUNET_NO;
156
157   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
158               "Comparing results name %s\n",
159               name);
160   if (0 != memcmp (zone_key,
161                    privkey,
162                    sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)))
163   {
164     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
165               "Monitoring returned wrong zone key\n");
166     GNUNET_break (0);
167     GNUNET_SCHEDULER_cancel (endbadly_task);
168     endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
169     return;
170   }
171
172   if (0 == strcmp (name, s_name_1))
173   {
174     if (GNUNET_YES != GNUNET_GNSRECORD_records_cmp(rd, s_rd_1))
175     {
176       GNUNET_break (0);
177         fail = GNUNET_YES;
178     }
179   }
180   else if (0 == strcmp (name, s_name_2))
181   {
182     if (GNUNET_YES != GNUNET_GNSRECORD_records_cmp(rd, 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",
192                 name);
193     GNUNET_break (0);
194     fail = GNUNET_YES;
195   }
196
197   if (2 == ++returned_records)
198   {
199     if (endbadly_task != NULL)
200     {
201       GNUNET_SCHEDULER_cancel (endbadly_task);
202       endbadly_task = NULL;
203     }
204     if (GNUNET_YES == fail)
205       GNUNET_SCHEDULER_add_now (&endbadly, NULL);
206     else
207         GNUNET_SCHEDULER_add_now (&end, NULL);
208   }
209 }
210
211
212 static void
213 put_cont (void *cls, int32_t success, 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 created records\n");
237     GNUNET_break (0);
238     GNUNET_SCHEDULER_cancel (endbadly_task);
239     endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
240   }
241 }
242
243
244 static struct GNUNET_GNSRECORD_Data *
245 create_record (unsigned int count)
246 {
247   unsigned int c;
248   struct GNUNET_GNSRECORD_Data * rd;
249
250   rd = GNUNET_malloc (count * sizeof (struct GNUNET_GNSRECORD_Data));
251   for (c = 0; c < count; c++)
252   {
253     rd[c].expiration_time = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_HOURS).abs_value_us;
254     rd[c].record_type = 1111;
255     rd[c].data_size = 50;
256     rd[c].data = GNUNET_malloc(50);
257     rd[c].flags = 0;
258     memset ((char *) rd[c].data, 'a', 50);
259   }
260   return rd;
261 }
262
263
264 static void
265 run (void *cls,
266      const struct GNUNET_CONFIGURATION_Handle *cfg,
267      struct GNUNET_TESTING_Peer *peer)
268 {
269   char *hostkey_file;
270
271   res = 1;
272
273   directory = NULL;
274   GNUNET_assert (GNUNET_OK ==
275                  GNUNET_CONFIGURATION_get_value_string(cfg, "PATHS", "GNUNET_TEST_HOME", &directory));
276   GNUNET_DISK_directory_remove (directory);
277
278   GNUNET_asprintf(&hostkey_file,
279                   "zonefiles%s%s",
280                   DIR_SEPARATOR_STR,
281                   "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey");
282   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
283               "Using zonekey file `%s' \n", hostkey_file);
284   privkey = GNUNET_CRYPTO_ecdsa_key_create_from_file(hostkey_file);
285   GNUNET_free (hostkey_file);
286   GNUNET_assert (privkey != NULL);
287
288   /* Start monitoring */
289   zm = GNUNET_NAMESTORE_zone_monitor_start (cfg,
290                                             privkey,
291                                             GNUNET_YES,
292                                             &zone_proc,
293                                             NULL,
294                                             NULL);
295   if (NULL == zm)
296   {
297     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
298                 "Failed to create zone monitor\n");
299     GNUNET_break (0);
300     endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
301     return;
302   }
303
304   endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &endbadly, NULL);
305   /* Connect to namestore */
306   nsh = GNUNET_NAMESTORE_connect (cfg);
307   if (NULL == nsh)
308   {
309     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Connect to namestore\n");
310     GNUNET_break (0);
311     endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
312     return;
313   }
314
315   GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",
316                   DIR_SEPARATOR_STR,
317                   "HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey");
318   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file);
319   privkey2 = GNUNET_CRYPTO_ecdsa_key_create_from_file(hostkey_file);
320   GNUNET_free (hostkey_file);
321   GNUNET_assert (privkey2 != NULL);
322
323
324   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "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] = GNUNET_NAMESTORE_records_store (nsh, privkey2, s_name_3,
329                 1, s_rd_3, &put_cont, s_name_3)));
330
331   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 1\n");
332   GNUNET_asprintf(&s_name_1, "dummy1");
333   s_rd_1 = create_record(1);
334   GNUNET_assert (NULL != (ns_ops[0] = GNUNET_NAMESTORE_records_store(nsh, privkey, s_name_1,
335                 1, s_rd_1, &put_cont, s_name_1)));
336
337
338   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 2 \n");
339   GNUNET_asprintf(&s_name_2, "dummy2");
340   s_rd_2 = create_record(1);
341   GNUNET_assert (NULL != (ns_ops[1] = GNUNET_NAMESTORE_records_store(nsh, privkey, s_name_2,
342                 1, s_rd_2, &put_cont, s_name_2)));
343
344
345 }
346
347
348 int
349 main (int argc, char *argv[])
350 {
351   res = 1;
352   if (0 !=
353       GNUNET_TESTING_peer_run ("test-namestore-api-monitoring",
354                                "test_namestore_api.conf",
355                                &run,
356                                NULL))
357   {
358     res = 1;
359   }
360   if (NULL != directory)
361   {
362       GNUNET_DISK_directory_remove (directory);
363       GNUNET_free (directory);
364   }
365   return res;
366 }
367
368
369 /* end of test_namestore_api_monitoring.c */