4c83cda6372dde2cc099bcc2f7ad66aa1f28218d
[oweals/gnunet.git] / src / namestore / test_namestore_api_remove.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 to: remove record
23  */
24 #include "platform.h"
25 #include "gnunet_namestore_service.h"
26 #include "gnunet_testing_lib.h"
27
28 #define TEST_RECORD_TYPE 1234
29
30 #define TEST_RECORD_DATALEN 123
31
32 #define TEST_RECORD_DATA 'a'
33
34 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 100)
35
36
37 static struct GNUNET_NAMESTORE_Handle *nsh;
38
39 static GNUNET_SCHEDULER_TaskIdentifier endbadly_task;
40
41 static struct GNUNET_CRYPTO_EccPrivateKey *privkey;
42
43 static struct GNUNET_CRYPTO_EccPublicSignKey pubkey;
44
45 static struct GNUNET_HashCode derived_hash;
46
47 static int res;
48
49 static int removed;
50
51 static struct GNUNET_NAMESTORE_QueueEntry *nsqe;
52
53
54 static void
55 cleanup ()
56 {
57   if (NULL != nsh)
58   {
59     GNUNET_NAMESTORE_disconnect (nsh);
60     nsh = NULL;
61   }
62   if (NULL != privkey)
63   {
64     GNUNET_free (privkey);
65     privkey = NULL;
66   }
67   GNUNET_SCHEDULER_shutdown ();
68 }
69
70
71 /**
72  * Re-establish the connection to the service.
73  *
74  * @param cls handle to use to re-connect.
75  * @param tc scheduler context
76  */
77 static void
78 endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
79 {
80   if (NULL != nsqe)
81   {
82     GNUNET_NAMESTORE_cancel (nsqe);
83     nsqe = NULL;
84   }
85   cleanup ();
86   res = 1;
87 }
88
89
90 static void
91 end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
92 {
93   cleanup ();
94   res = 0;
95 }
96
97 static void
98 name_lookup_proc (void *cls, const struct GNUNET_NAMESTORE_Block *block);
99
100
101 static void
102 remove_cont (void *cls, 
103              int32_t success, 
104              const char *emsg)
105 {
106   const char *name = cls;
107   if (GNUNET_YES != success)
108   {
109     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
110               _("Records could not be removed: `%s'\n"), emsg);
111     if (endbadly_task != GNUNET_SCHEDULER_NO_TASK)
112       GNUNET_SCHEDULER_cancel (endbadly_task);
113     endbadly_task =  GNUNET_SCHEDULER_add_now (&endbadly, NULL);
114     return;
115   }
116
117   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
118               "Records were removed, perform lookup\n");
119
120   removed = GNUNET_YES;
121   nsqe = GNUNET_NAMESTORE_lookup_block (nsh, &derived_hash,
122                                          &name_lookup_proc, (void *) name);
123   if (NULL == nsqe)
124   {
125         GNUNET_break (0);
126     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
127               _("Namestore cannot perform lookup for removed record\n"));
128     if (endbadly_task != GNUNET_SCHEDULER_NO_TASK)
129       GNUNET_SCHEDULER_cancel (endbadly_task);
130     endbadly_task =  GNUNET_SCHEDULER_add_now (&endbadly, NULL);
131     return;
132   }
133 }
134
135
136 static void
137 rd_decrypt_cb (void *cls,
138                unsigned int rd_count,
139                const struct GNUNET_NAMESTORE_RecordData *rd)
140 {
141   const char *name = cls;
142   char rd_cmp_data[TEST_RECORD_DATALEN];
143
144   GNUNET_assert (GNUNET_NO == removed);
145   GNUNET_assert (1 == rd_count);
146   GNUNET_assert (NULL != rd);  
147   memset (rd_cmp_data, 'a', TEST_RECORD_DATALEN);
148   
149   GNUNET_assert (TEST_RECORD_TYPE == rd[0].record_type);
150   GNUNET_assert (TEST_RECORD_DATALEN == rd[0].data_size);
151   GNUNET_assert (0 == memcmp (&rd_cmp_data, rd[0].data, TEST_RECORD_DATALEN));
152   
153   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
154               "Block was decrypted successfully, removing records \n");
155   
156   nsqe = GNUNET_NAMESTORE_records_store (nsh, privkey, name,
157                                          0, NULL, &remove_cont, (void *) name);
158 }
159
160
161 static void
162 name_lookup_proc (void *cls,
163                   const struct GNUNET_NAMESTORE_Block *block)
164 {
165   const char *name = cls;
166   nsqe = NULL;
167
168   if (removed && (NULL == block))
169   {
170     if (endbadly_task != GNUNET_SCHEDULER_NO_TASK)
171     {
172       GNUNET_SCHEDULER_cancel (endbadly_task);
173       endbadly_task = GNUNET_SCHEDULER_NO_TASK;
174     }
175     GNUNET_SCHEDULER_add_now (&end, NULL);
176     return;
177   }
178   GNUNET_assert (NULL != cls);
179   if (endbadly_task != GNUNET_SCHEDULER_NO_TASK)
180   {
181     GNUNET_SCHEDULER_cancel (endbadly_task);
182     endbadly_task = GNUNET_SCHEDULER_NO_TASK;
183   }
184
185   if (NULL == block)
186   {
187     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
188               _("Namestore returned no block\n"));
189     if (endbadly_task != GNUNET_SCHEDULER_NO_TASK)
190       GNUNET_SCHEDULER_cancel (endbadly_task);
191     endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
192     return;
193   }
194   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
195               "Namestore returned block, decrypting \n");
196   GNUNET_assert (GNUNET_OK == 
197                  GNUNET_NAMESTORE_block_decrypt (block,
198                                                  &pubkey, name, &rd_decrypt_cb, (void *) name));
199 }
200
201
202 static void
203 put_cont (void *cls, int32_t success, 
204           const char *emsg)
205 {
206   const char *name = cls;
207
208   GNUNET_assert (NULL != cls);
209   if (GNUNET_SYSERR == success)
210   {
211     GNUNET_break (0);
212     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
213                 "Namestore could not store record: `%s'\n", 
214                 emsg);
215     if (endbadly_task != GNUNET_SCHEDULER_NO_TASK)
216       GNUNET_SCHEDULER_cancel (endbadly_task);
217     endbadly_task =  GNUNET_SCHEDULER_add_now (&endbadly, NULL);
218     return;
219   }
220
221   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
222               "Name store added record for `%s': %s\n",
223               name,
224               (success == GNUNET_OK) ? "SUCCESS" : "FAIL");
225
226   /* Create derived hash */
227   GNUNET_NAMESTORE_query_from_private_key (privkey,
228                                            name,
229                                            &derived_hash);
230
231   nsqe = GNUNET_NAMESTORE_lookup_block (nsh, &derived_hash,
232                                         &name_lookup_proc, (void *) name);
233   if (NULL == nsqe)
234   {
235     GNUNET_break (0);
236     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
237               _("Namestore cannot perform lookup\n"));
238     if (endbadly_task != GNUNET_SCHEDULER_NO_TASK)
239       GNUNET_SCHEDULER_cancel (endbadly_task);
240     endbadly_task =  GNUNET_SCHEDULER_add_now (&endbadly, NULL);
241     return;
242   }
243 }
244
245
246 static void
247 run (void *cls, 
248      const struct GNUNET_CONFIGURATION_Handle *cfg,
249      struct GNUNET_TESTING_Peer *peer)
250 {
251   struct GNUNET_NAMESTORE_RecordData rd;
252   char *hostkey_file;
253   const char * name = "dummy.dummy.gnunet";
254
255   endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
256                                                 &endbadly, NULL);
257   GNUNET_asprintf (&hostkey_file,
258                    "zonefiles%s%s",
259                    DIR_SEPARATOR_STR,
260                    "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey");
261   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file);
262   privkey = GNUNET_CRYPTO_ecc_key_create_from_file (hostkey_file);
263   GNUNET_free (hostkey_file);
264   GNUNET_assert (privkey != NULL);
265   GNUNET_CRYPTO_ecc_key_get_public_for_signature (privkey, &pubkey);
266
267   removed = GNUNET_NO;
268
269   rd.expiration_time = GNUNET_TIME_absolute_get().abs_value_us;
270   rd.record_type = TEST_RECORD_TYPE;
271   rd.data_size = TEST_RECORD_DATALEN;
272   rd.data = GNUNET_malloc (TEST_RECORD_DATALEN);
273   memset ((char *) rd.data, 'a', TEST_RECORD_DATALEN);
274
275   nsh = GNUNET_NAMESTORE_connect (cfg);
276   GNUNET_break (NULL != nsh);
277   nsqe = GNUNET_NAMESTORE_records_store (nsh, privkey, name,
278                                       1, &rd, &put_cont, (void *) name);
279   if (NULL == nsqe)
280   {
281     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
282               _("Namestore cannot store no block\n"));
283   }
284   GNUNET_free ((void *)rd.data);
285 }
286
287
288 int
289 main (int argc, char *argv[])
290 {
291   res = 1;
292   if (0 != 
293       GNUNET_TESTING_service_run ("test-namestore-api",
294                                   "namestore",
295                                   "test_namestore_api.conf",
296                                   &run,
297                                   NULL))
298     return 1;
299   return res;
300 }
301
302 /* end of test_namestore_api.c */