0b08cfe8fa293e499296910b0cc10e7e4135bc9d
[oweals/gnunet.git] / src / datastore / test_datastore_api.c
1 /*
2      This file is part of GNUnet.
3      (C) 2004, 2005, 2006, 2007, 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 2, 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 datastore/test_datastore_api.c
22  * @brief Test for the datastore implementation.
23  * @author Christian Grothoff
24  *
25  * TODO:
26  * - test multiple values under same key
27  * - test "update"
28  * - test storage reservations
29  */
30
31 #include "platform.h"
32 #include "gnunet_util_lib.h"
33 #include "gnunet_protocols.h"
34 #include "gnunet_datastore_service.h"
35
36 static struct GNUNET_DATASTORE_Handle *datastore;
37
38 static struct GNUNET_TIME_Absolute now;
39
40
41 static size_t
42 get_size (int i)
43 {
44   return 8 * i;
45 }
46
47
48 static const void *
49 get_data (int i)
50 {
51   static char buf[60000]; 
52   memset (buf, i, 8 * i);
53   return buf;
54 }
55
56
57 static int
58 get_type(int i)
59 {
60   return i;
61 }
62
63
64 static int 
65 get_priority (int i)
66 {
67   return i+1;
68 }
69
70
71 static int
72 get_anonymity(int i)
73 {
74   return i;
75 }
76
77
78 static struct GNUNET_TIME_Absolute 
79 get_expiration (int i)
80 {
81   struct GNUNET_TIME_Absolute av;
82
83   av.value = now.value - i * 1000;
84   return av;
85 }
86
87
88 static void
89 check_success (void *cls,
90                int success,
91                const char *msg)
92 {
93   GNUNET_assert (GNUNET_OK == success);
94 }
95
96
97 static void
98 check_failure (void *cls,
99                int success,
100                const char *msg)
101 {
102   GNUNET_assert (GNUNET_OK != success);
103   GNUNET_assert (NULL != msg);
104 }
105
106
107 static void 
108 check_value (void *cls,
109              const GNUNET_HashCode * key,
110              uint32_t size,
111              const void *data,
112              uint32_t type,
113              uint32_t priority,
114              uint32_t anonymity,
115              struct GNUNET_TIME_Absolute
116              expiration, uint64_t uid)
117 {
118   int *iptr = cls;
119   int i;
120
121   if (key == NULL)
122     return;
123   i = *iptr;
124   GNUNET_assert (size == get_size (i));
125   GNUNET_assert (0 == memcmp (data, get_data(i), size));
126   GNUNET_assert (type == get_type (i));
127   GNUNET_assert (priority == get_priority (i));
128   GNUNET_assert (anonymity == get_anonymity(i));
129   GNUNET_assert (expiration.value == get_expiration(i).value);
130 }
131
132
133 static void 
134 delete_value (void *cls,
135              const GNUNET_HashCode * key,
136              uint32_t size,
137              const void *data,
138              uint32_t type,
139              uint32_t priority,
140              uint32_t anonymity,
141              struct GNUNET_TIME_Absolute
142              expiration, uint64_t uid)
143 {
144   if (key == NULL)
145     return;
146   GNUNET_DATASTORE_remove (datastore,
147                            key,
148                            size,
149                            data,
150                            &check_success,
151                            NULL);
152   ((int*)key)[0]++;
153   GNUNET_DATASTORE_remove (datastore,
154                            key,
155                            size,
156                            data,
157                            &check_failure,
158                            NULL);
159 }
160
161
162
163 static void 
164 check_nothing (void *cls,
165              const GNUNET_HashCode * key,
166              uint32_t size,
167              const void *data,
168              uint32_t type,
169              uint32_t priority,
170              uint32_t anonymity,
171              struct GNUNET_TIME_Absolute
172              expiration, uint64_t uid)
173 {
174   GNUNET_assert (key == NULL);
175 }
176
177
178
179 static void
180 run (void *cls,
181      struct GNUNET_SCHEDULER_Handle *sched,
182      char *const *args,
183      const char *cfgfile, struct GNUNET_CONFIGURATION_Handle *cfg)
184 {
185   GNUNET_HashCode key;
186   int i;
187   int *iptr;
188
189   datastore = GNUNET_DATASTORE_connect (cfg, sched);
190   now.value = 1000000;
191   for (i = 0; i < 256; i++)
192     {
193       memset (&key, 256 - i, sizeof (GNUNET_HashCode));
194       GNUNET_DATASTORE_put (datastore,
195                             0,
196                             &key,
197                             get_size (i),
198                             get_data (i),
199                             get_type (i),
200                             get_priority (i),
201                             get_anonymity (i),
202                             get_expiration (i),
203                             &check_success,
204                             NULL);
205     }
206   for (i = 255; i >= 0; i--)
207     {
208       memset (&key, 256 - i, sizeof (GNUNET_HashCode));
209       iptr = GNUNET_malloc(sizeof(int));
210       *iptr = i;
211       GNUNET_DATASTORE_get (datastore, 
212                             &key,
213                             get_type (i),
214                             &check_value,
215                             iptr);
216     }
217   for (i = 255; i >= 0; i--)
218     {
219       memset (&key, 256 - i, sizeof (GNUNET_HashCode));
220       iptr = GNUNET_malloc(sizeof(int));
221       *iptr = i;
222       GNUNET_DATASTORE_get (datastore, 
223                             &key,
224                             get_type (i),
225                             &delete_value,
226                             iptr);
227     }
228   for (i = 255; i >= 0; i--)
229     {
230       memset (&key, 256 - i, sizeof (GNUNET_HashCode));
231       iptr = GNUNET_malloc(sizeof(int));
232       *iptr = i;
233       GNUNET_DATASTORE_get (datastore, 
234                             &key,
235                             get_type (i),
236                             &check_nothing,
237                             iptr);
238     }
239   /* check reservations */
240
241   /* check update */
242
243   /* test multiple results */
244
245   GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES);
246 }
247
248
249
250 static int
251 check ()
252 {
253   int ok = 1 + 2 + 4 + 8;
254   pid_t pid;
255   char *const argv[] = { "test-datastore-api",
256     "-c",
257     "test_datastore_api_data.conf",
258 #if VERBOSE
259     "-L", "DEBUG",
260 #endif
261     NULL
262   };
263   struct GNUNET_GETOPT_CommandLineOption options[] = {
264     GNUNET_GETOPT_OPTION_END
265   };
266   pid = GNUNET_OS_start_process ("gnunet-service-datastore",
267                                  "gnunet-service-datastore",
268 #if VERBOSE
269                                  "-L", "DEBUG",
270 #endif
271                                  "-c", "test_datastore_api_data.conf", NULL);
272   sleep (1);
273   GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
274                       argv, "test-datastore-api", "nohelp",
275                       options, &run, &ok);
276   if (0 != PLIBC_KILL (pid, SIGTERM))
277     {
278       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
279       ok = 1;
280     }
281   GNUNET_OS_process_wait(pid);
282   if (ok != 0)
283     fprintf (stderr, "Missed some testcases: %u\n", ok);
284   return ok;
285 }
286
287 int
288 main (int argc, char *argv[])
289 {
290   int ret;
291
292   GNUNET_log_setup ("test-datastore-api",
293 #if VERBOSE
294                     "DEBUG",
295 #else
296                     "WARNING",
297 #endif
298                     NULL);
299   ret = check ();
300
301   return ret;
302 }
303
304
305
306 /* end of test_datastore_api.c */