-bugfixes, code cleanup
[oweals/gnunet.git] / src / namestore / test_namestore_api_lookup.c
1 /*
2      This file is part of GNUnet.
3      (C) 2012 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_lookup.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 "gnunet_testing_lib-new.h"
28 #include "namestore.h"
29 #include "gnunet_signatures.h"
30
31 #define RECORDS 5
32
33 #define TEST_RECORD_TYPE 1234
34
35 #define TEST_RECORD_DATALEN 123
36
37 #define TEST_RECORD_DATA 'a'
38
39 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 100)
40
41
42 static struct GNUNET_NAMESTORE_Handle * nsh;
43
44 static GNUNET_SCHEDULER_TaskIdentifier endbadly_task;
45
46 static struct GNUNET_CRYPTO_RsaPrivateKey * privkey;
47
48 static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey;
49
50 static struct GNUNET_CRYPTO_RsaSignature *s_signature;
51
52 static struct GNUNET_CRYPTO_ShortHashCode s_zone;
53
54 static struct GNUNET_NAMESTORE_RecordData *s_rd;
55
56 static struct GNUNET_NAMESTORE_QueueEntry *nsqe;
57
58 static char *s_name;
59
60 static int res;
61
62
63 static void
64 cleanup ()
65 {
66   if (NULL != nsh)
67   {
68     GNUNET_NAMESTORE_disconnect (nsh);
69     nsh = NULL;
70   }
71   if (NULL != privkey)
72   {
73     GNUNET_CRYPTO_rsa_key_free (privkey);
74     privkey = NULL;
75   }
76   GNUNET_SCHEDULER_shutdown ();
77 }
78
79
80 /**
81  * Re-establish the connection to the service.
82  *
83  * @param cls handle to use to re-connect.
84  * @param tc scheduler context
85  */
86 static void
87 endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
88 {
89   cleanup ();
90   res = 1;
91 }
92
93
94 static void
95 end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
96 {
97   unsigned int c;
98
99   for (c = 0; c < RECORDS; c++)
100     GNUNET_free_non_null((void *) s_rd[c].data);
101   GNUNET_free (s_rd);
102   cleanup ();
103 }
104
105
106 static void
107 name_lookup_proc (void *cls,
108                   const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
109                   struct GNUNET_TIME_Absolute expire,
110                   const char *n,
111                   unsigned int rd_count,
112                   const struct GNUNET_NAMESTORE_RecordData *rd,
113                   const struct GNUNET_CRYPTO_RsaSignature *signature)
114 {
115   static int found = GNUNET_NO;
116   int c;
117
118   if (NULL != n)
119   {
120     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking returned results\n");
121     if (0 != memcmp (zone_key, &pubkey, 
122                      sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)))
123     {
124       GNUNET_break (0);
125     }
126     GNUNET_assert (NULL != signature);
127     if (0 != memcmp (signature, s_signature, 
128                      sizeof (struct GNUNET_CRYPTO_RsaSignature)))
129     {
130       GNUNET_break (0);
131     }
132     if (0 != strcmp (n, s_name))
133     {
134       GNUNET_break (0);
135     }
136     if (RECORDS != rd_count)
137     {
138       GNUNET_break (0);
139     }
140     for (c = 0; c < RECORDS; c++)
141     {
142       if (GNUNET_NO == GNUNET_NAMESTORE_records_cmp (&rd[c], &s_rd[c]))
143       {
144         GNUNET_break (0);
145       }
146     }
147     found = GNUNET_YES;
148     res = 0;
149   }
150   else
151   {
152     if (GNUNET_YES != found)
153     {
154       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
155                   "Failed to lookup records for name `%s'\n", s_name);
156       res = 1;
157     }
158     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Lookup done for name %s'\n", s_name);
159   }
160   if (GNUNET_SCHEDULER_NO_TASK != endbadly_task)
161   {
162     GNUNET_SCHEDULER_cancel (endbadly_task);
163     endbadly_task = GNUNET_SCHEDULER_NO_TASK;
164   }
165   GNUNET_SCHEDULER_add_now (&end, NULL);
166 }
167
168
169 static void
170 put_cont (void *cls, int32_t success, const char *emsg)
171 {
172   char * name = cls;
173
174   nsqe = NULL;
175   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
176               "Name store added record for `%s': %s\n", name, 
177               (GNUNET_OK == success) ? "SUCCESS" : "FAIL");
178   if (GNUNET_OK == success)
179   {
180     res = 0;
181     GNUNET_NAMESTORE_lookup_record (nsh, &s_zone, name, 0, 
182                                     &name_lookup_proc, NULL);
183   }
184   else
185   {
186     res = 1;
187     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
188                 "Failed to put records for name `%s'\n", name);
189     GNUNET_SCHEDULER_shutdown ();
190   }
191 }
192
193
194 static struct GNUNET_NAMESTORE_RecordData *
195 create_record (unsigned int count)
196 {
197   unsigned int c;
198   struct GNUNET_NAMESTORE_RecordData * rd;
199
200   rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData));
201   for (c = 0; c < count; c++)
202   {
203     rd[c].expiration_time = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_HOURS).abs_value;
204     rd[c].record_type = TEST_RECORD_TYPE;
205     rd[c].data_size = TEST_RECORD_DATALEN;
206     rd[c].data = GNUNET_malloc(TEST_RECORD_DATALEN);
207     memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN);
208   }
209   return rd;
210 }
211
212
213 static void
214 run (void *cls, 
215      const struct GNUNET_CONFIGURATION_Handle *cfg,
216      struct GNUNET_TESTING_Peer *peer)
217 {
218   size_t rd_ser_len;
219   struct GNUNET_TIME_Absolute et;
220   char rd_ser[rd_ser_len];
221
222   endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
223                                                 &endbadly, NULL);
224
225   /* load privat key from file not included in zonekey dir */
226   privkey = GNUNET_CRYPTO_rsa_key_create_from_file("test_hostkey");
227   GNUNET_assert (NULL != privkey);
228   /* get public key */
229   GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey);
230
231   /* create record */
232   s_name = "dummy.dummy.gnunet";
233   s_rd = create_record (RECORDS);
234
235   rd_ser_len = GNUNET_NAMESTORE_records_get_size(RECORDS, s_rd);
236   GNUNET_NAMESTORE_records_serialize(RECORDS, s_rd, rd_ser_len, rd_ser);
237
238   /* sign */
239   et.abs_value = s_rd[0].expiration_time;
240   s_signature = GNUNET_NAMESTORE_create_signature (privkey, et, s_name, 
241                                                    s_rd, RECORDS);
242   
243   /* create random zone hash */
244   GNUNET_CRYPTO_short_hash (&pubkey, 
245                             sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), 
246                             &s_zone);
247   nsh = GNUNET_NAMESTORE_connect (cfg);
248   GNUNET_break (NULL != nsh);
249   nsqe = GNUNET_NAMESTORE_record_put (nsh, &pubkey, s_name,
250                                       GNUNET_TIME_UNIT_FOREVER_ABS,
251                                       RECORDS, s_rd, s_signature, 
252                                       &put_cont, s_name);
253 }
254
255
256 int
257 main (int argc, char *argv[])
258 {
259   res = 1;
260   if (0 != 
261       GNUNET_TESTING_service_run ("test-namestore-api-lookup",
262                                   "namestore",
263                                   "test_namestore_api.conf",
264                                   &run,
265                                   NULL))
266     return 1;
267   GNUNET_free_non_null (s_signature);
268   return res;
269 }
270
271
272 /* end of test_namestore_api_lookup.c */