-renaming gnunet-gns to gnunet-namestore
[oweals/gnunet.git] / src / namestore / test_namestore_api_lookup_specific_type.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009 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., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20 /**
21  * @file namestore/test_namestore_api.c
22  * @brief testcase for namestore_api.c
23  */
24 #include "platform.h"
25 #include "gnunet_common.h"
26 #include "gnunet_namestore_service.h"
27 #include "namestore.h"
28 #include "gnunet_signatures.h"
29
30 #define VERBOSE GNUNET_NO
31
32 #define RECORDS 5
33 #define TEST_RECORD_TYPE 1234
34 #define TEST_RECORD_DATALEN 123
35 #define TEST_RECORD_DATA 'a'
36
37 #define TEST_RECORD_LOOKUP_TYPE_NOT_EXISTING 11111
38 #define TEST_RECORD_LOOKUP_TYPE_EXISTING 22222
39
40 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
41
42 static struct GNUNET_NAMESTORE_Handle * nsh;
43
44 static GNUNET_SCHEDULER_TaskIdentifier endbadly_task;
45 static struct GNUNET_OS_Process *arm;
46
47 static struct GNUNET_CRYPTO_RsaPrivateKey * privkey;
48 static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey;
49 struct GNUNET_CRYPTO_RsaSignature *s_signature;
50 static GNUNET_HashCode s_zone;
51 struct GNUNET_NAMESTORE_RecordData *s_rd;
52 static char *s_name;
53
54
55
56 static int res;
57
58 static void
59 start_arm (const char *cfgname)
60 {
61   arm = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm",
62                                "gnunet-service-arm", "-c", cfgname,
63 #if VERBOSE_PEERS
64                                "-L", "DEBUG",
65 #else
66                                "-L", "ERROR",
67 #endif
68                                NULL);
69 }
70
71 static void
72 stop_arm ()
73 {
74   if (NULL != arm)
75   {
76     if (0 != GNUNET_OS_process_kill (arm, SIGTERM))
77       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
78     GNUNET_OS_process_wait (arm);
79     GNUNET_OS_process_close (arm);
80     arm = NULL;
81   }
82 }
83
84 /**
85  * Re-establish the connection to the service.
86  *
87  * @param cls handle to use to re-connect.
88  * @param tc scheduler context
89  */
90 static void
91 endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
92 {
93   if (nsh != NULL)
94     GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
95   nsh = NULL;
96
97   if (privkey != NULL)
98     GNUNET_CRYPTO_rsa_key_free (privkey);
99   privkey = NULL;
100
101   if (NULL != arm)
102     stop_arm();
103
104   res = 1;
105 }
106
107
108 static void
109 end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
110 {
111   if (endbadly_task != GNUNET_SCHEDULER_NO_TASK)
112   {
113     GNUNET_SCHEDULER_cancel (endbadly_task);
114     endbadly_task = GNUNET_SCHEDULER_NO_TASK;
115   }
116
117   int c;
118   for (c = 0; c < RECORDS; c++)
119   {
120     GNUNET_free_non_null((void *) s_rd[c].data);
121   }
122   GNUNET_free (s_rd);
123
124   if (privkey != NULL)
125     GNUNET_CRYPTO_rsa_key_free (privkey);
126   privkey = NULL;
127
128   if (nsh != NULL)
129     GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
130   nsh = NULL;
131
132   if (NULL != arm)
133     stop_arm();
134 }
135
136
137 void name_lookup_existing_record_type (void *cls,
138                             const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
139                             struct GNUNET_TIME_Absolute expire,
140                             const char *n,
141                             unsigned int rd_count,
142                             const struct GNUNET_NAMESTORE_RecordData *rd,
143                             const struct GNUNET_CRYPTO_RsaSignature *signature)
144 {
145   int failed = GNUNET_NO;
146
147   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Namestore returned %u records\n", rd_count);
148
149   if ((NULL == n) || (0 != memcmp(zone_key, &pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded))))
150   {
151     GNUNET_break(0);
152     failed = GNUNET_YES;
153   }
154   if ((NULL == n) || (0 != strcmp(n, s_name)))
155   {
156     GNUNET_break(0);
157     failed = GNUNET_YES;
158   }
159   if (1 != rd_count)
160   {
161     GNUNET_break(0);
162     failed = GNUNET_YES;
163   }
164   if (NULL == rd)
165   {
166     GNUNET_break(0);
167     failed = GNUNET_YES;
168   }
169   if (NULL != signature)
170   {
171     GNUNET_break(0);
172     failed = GNUNET_YES;
173   }
174
175   if (failed == GNUNET_YES)
176   {
177     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Namestore returned invalid response\n");
178     res = 1;
179   }
180   else
181   {
182    res = 0;
183   }
184
185   GNUNET_SCHEDULER_add_now(&end, NULL);
186 }
187
188
189 void name_lookup_non_existing_record_type (void *cls,
190                             const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
191                             struct GNUNET_TIME_Absolute expire,
192                             const char *n,
193                             unsigned int rd_count,
194                             const struct GNUNET_NAMESTORE_RecordData *rd,
195                             const struct GNUNET_CRYPTO_RsaSignature *signature)
196 {
197   int failed = GNUNET_NO;
198
199   if ((NULL == zone_key) || (0 != memcmp(zone_key, &pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded))))
200   {
201     GNUNET_break(0);
202     failed = GNUNET_YES;
203   }
204   if ((NULL == n) || (0 != strcmp(n, s_name)))
205   {
206     GNUNET_break(0);
207     failed = GNUNET_YES;
208   }
209   if (0 != rd_count)
210   {
211     GNUNET_break(0);
212     failed = GNUNET_YES;
213   }
214   if (NULL != rd)
215   {
216     GNUNET_break(0);
217     failed = GNUNET_YES;
218   }
219   if (NULL != signature)
220   {
221     GNUNET_break(0);
222     failed = GNUNET_YES;
223   }
224
225   if ((rd_count == 1) && (rd != NULL))
226   {
227     if (GNUNET_NO == GNUNET_NAMESTORE_records_cmp(rd, &rd[RECORDS-1]))
228     {
229       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Records are not equal!\n");
230       failed = GNUNET_YES;
231     }
232     else
233     {
234       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Records are equal!\n");
235     }
236   }
237
238   if (failed == GNUNET_YES)
239   {
240     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Namestore returned invalid response\n");
241     res = 1;
242
243   }
244   else
245   {
246    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Namestore returned valid response\n");
247    GNUNET_NAMESTORE_lookup_record (nsh, &s_zone, s_name, TEST_RECORD_LOOKUP_TYPE_EXISTING, &name_lookup_existing_record_type, NULL);
248    res = 0;
249   }
250 }
251
252 void
253 put_cont (void *cls, int32_t success, const char *emsg)
254 {
255   char * name = cls;
256
257   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name store added record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL");
258   if (success == GNUNET_OK)
259   {
260     res = 0;
261     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Looking up non-existing record type %u for name `%s'\n", TEST_RECORD_LOOKUP_TYPE_NOT_EXISTING, name);
262     GNUNET_NAMESTORE_lookup_record (nsh, &s_zone, name, TEST_RECORD_LOOKUP_TYPE_NOT_EXISTING, &name_lookup_non_existing_record_type, NULL);
263   }
264   else
265   {
266     res = 1;
267     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name);
268     GNUNET_SCHEDULER_add_now(&end, NULL);
269   }
270 }
271
272 static struct GNUNET_NAMESTORE_RecordData *
273 create_record (int count)
274 {
275   int c;
276   struct GNUNET_NAMESTORE_RecordData * rd;
277   rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData));
278
279   for (c = 0; c < RECORDS-1; c++)
280   {
281   rd[c].expiration = GNUNET_TIME_absolute_get();
282   rd[c].record_type = 1;
283   rd[c].data_size = TEST_RECORD_DATALEN;
284   rd[c].data = GNUNET_malloc(TEST_RECORD_DATALEN);
285   memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN);
286   }
287
288   rd[c].expiration = GNUNET_TIME_absolute_get();
289   rd[c].record_type = TEST_RECORD_LOOKUP_TYPE_EXISTING;
290   rd[c].data_size = TEST_RECORD_DATALEN;
291   rd[c].data = GNUNET_malloc(TEST_RECORD_DATALEN);
292   memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN);
293
294
295   return rd;
296 }
297
298 void
299 delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg)
300 {
301   char *afsdir;
302
303   if (GNUNET_OK ==
304       GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite",
305                                                "FILENAME", &afsdir))
306   {
307     if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
308       if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
309         if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir))
310           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir);
311    GNUNET_free (afsdir);
312   }
313
314 }
315
316 static void
317 run (void *cls, char *const *args, const char *cfgfile,
318      const struct GNUNET_CONFIGURATION_Handle *cfg)
319 {
320   delete_existing_db(cfg);
321   endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,endbadly, NULL);
322
323   size_t rd_ser_len;
324
325   /* load privat key */
326   privkey = GNUNET_CRYPTO_rsa_key_create_from_file("hostkey");
327   GNUNET_assert (privkey != NULL);
328   /* get public key */
329   GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey);
330
331   /* create record */
332   s_name = "dummy.dummy.gnunet";
333   s_rd = create_record (RECORDS);
334
335   rd_ser_len = GNUNET_NAMESTORE_records_get_size(RECORDS, s_rd);
336   char rd_ser[rd_ser_len];
337   GNUNET_NAMESTORE_records_serialize(RECORDS, s_rd, rd_ser_len, rd_ser);
338
339   /* sign */
340   s_signature = GNUNET_NAMESTORE_create_signature(privkey, s_name, s_rd, RECORDS);
341
342   /* create random zone hash */
343   GNUNET_CRYPTO_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &s_zone);
344
345   start_arm (cfgfile);
346   GNUNET_assert (arm != NULL);
347
348   nsh = GNUNET_NAMESTORE_connect (cfg);
349   GNUNET_break (NULL != nsh);
350
351   GNUNET_break (s_rd != NULL);
352   GNUNET_break (s_name != NULL);
353
354   GNUNET_NAMESTORE_record_put (nsh, &pubkey, s_name,
355                               GNUNET_TIME_absolute_get_forever(),
356                               RECORDS, s_rd, s_signature, put_cont, s_name);
357
358
359
360 }
361
362 static int
363 check ()
364 {
365   static char *const argv[] = { "test-namestore-api",
366     "-c",
367     "test_namestore_api.conf",
368 #if VERBOSE
369     "-L", "DEBUG",
370 #endif
371     NULL
372   };
373   static struct GNUNET_GETOPT_CommandLineOption options[] = {
374     GNUNET_GETOPT_OPTION_END
375   };
376
377   res = 1;
378   GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-namestore-api",
379                       "nohelp", options, &run, &res);
380   return res;
381 }
382
383 int
384 main (int argc, char *argv[])
385 {
386   int ret;
387
388   ret = check ();
389   GNUNET_free (s_signature);
390   return ret;
391 }
392
393 /* end of test_namestore_api.c */