diff options
author | Gabor X Toth <*@tg-x.net> | 2013-09-03 22:33:21 +0000 |
---|---|---|
committer | Gabor X Toth <*@tg-x.net> | 2013-09-03 22:33:21 +0000 |
commit | eb9556bf2983ca19a5cbcf7cf460a0b2509b290a (patch) | |
tree | 285d31e951f7ecf9308b22257adcadd5b07d80ea /src/psycstore/test_plugin_psycstore.c | |
parent | 37bafa60a6f0e447cb5b61547404f0902fa7ad41 (diff) | |
download | gnunet-eb9556bf2983ca19a5cbcf7cf460a0b2509b290a.tar.gz gnunet-eb9556bf2983ca19a5cbcf7cf460a0b2509b290a.zip |
PSYCstore SQLite backend; API fixes/enhancements
Diffstat (limited to 'src/psycstore/test_plugin_psycstore.c')
-rw-r--r-- | src/psycstore/test_plugin_psycstore.c | 375 |
1 files changed, 375 insertions, 0 deletions
diff --git a/src/psycstore/test_plugin_psycstore.c b/src/psycstore/test_plugin_psycstore.c new file mode 100644 index 000000000..52a306f07 --- /dev/null +++ b/src/psycstore/test_plugin_psycstore.c | |||
@@ -0,0 +1,375 @@ | |||
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 psycstore/test_plugin_psycstore.c | ||
22 | * @brief Test for the psycstore plugins | ||
23 | * @author Gabor X Toth | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_testing_lib.h" | ||
29 | #include "gnunet_psycstore_plugin.h" | ||
30 | #include "gnunet_psycstore_service.h" | ||
31 | #include "gnunet_multicast_service.h" | ||
32 | |||
33 | #define DEBUG_PSYCSTORE GNUNET_EXTRA_LOGGING | ||
34 | #if DEBUG_PSYCSTORE | ||
35 | # define LOG_LEVEL "DEBUG" | ||
36 | #else | ||
37 | # define LOG_LEVEL "WARNING" | ||
38 | #endif | ||
39 | |||
40 | #define C2ARG(str) str, (sizeof (str) - 1) | ||
41 | |||
42 | #define LOG(kind,...) GNUNET_log_from (kind, "test-plugin-psycstore", __VA_ARGS__) | ||
43 | |||
44 | #define ASSERT(x) do { if (! (x)) { printf("Error at %s:%d\n", __FILE__, __LINE__); goto FAILURE;} } while (0) | ||
45 | |||
46 | static int ok; | ||
47 | |||
48 | /** | ||
49 | * Name of plugin under test. | ||
50 | */ | ||
51 | static const char *plugin_name; | ||
52 | |||
53 | static struct GNUNET_CRYPTO_EccPrivateKey *channel_key; | ||
54 | static struct GNUNET_CRYPTO_EccPrivateKey *slave_key; | ||
55 | |||
56 | static struct GNUNET_CRYPTO_EccPublicKey channel_pub_key; | ||
57 | static struct GNUNET_CRYPTO_EccPublicKey slave_pub_key; | ||
58 | |||
59 | /** | ||
60 | * Function called when the service shuts down. Unloads our psycstore | ||
61 | * plugin. | ||
62 | * | ||
63 | * @param api api to unload | ||
64 | */ | ||
65 | static void | ||
66 | unload_plugin (struct GNUNET_PSYCSTORE_PluginFunctions *api) | ||
67 | { | ||
68 | char *libname; | ||
69 | |||
70 | GNUNET_asprintf (&libname, "libgnunet_plugin_psycstore_%s", plugin_name); | ||
71 | GNUNET_break (NULL == GNUNET_PLUGIN_unload (libname, api)); | ||
72 | GNUNET_free (libname); | ||
73 | } | ||
74 | |||
75 | |||
76 | /** | ||
77 | * Load the psycstore plugin. | ||
78 | * | ||
79 | * @param cfg configuration to pass | ||
80 | * @return NULL on error | ||
81 | */ | ||
82 | static struct GNUNET_PSYCSTORE_PluginFunctions * | ||
83 | load_plugin (const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
84 | { | ||
85 | struct GNUNET_PSYCSTORE_PluginFunctions *ret; | ||
86 | char *libname; | ||
87 | |||
88 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Loading `%s' psycstore plugin\n"), | ||
89 | plugin_name); | ||
90 | GNUNET_asprintf (&libname, "libgnunet_plugin_psycstore_%s", plugin_name); | ||
91 | if (NULL == (ret = GNUNET_PLUGIN_load (libname, (void*) cfg))) | ||
92 | { | ||
93 | FPRINTF (stderr, "Failed to load plugin `%s'!\n", plugin_name); | ||
94 | return NULL; | ||
95 | } | ||
96 | GNUNET_free (libname); | ||
97 | return ret; | ||
98 | } | ||
99 | |||
100 | |||
101 | struct FragmentClosure | ||
102 | { | ||
103 | uint8_t n; | ||
104 | uint64_t flags[16]; | ||
105 | struct GNUNET_MULTICAST_MessageHeader *msg[16]; | ||
106 | }; | ||
107 | |||
108 | static int | ||
109 | fragment_cb (void *cls, struct GNUNET_MULTICAST_MessageHeader *msg2, | ||
110 | enum GNUNET_PSYCSTORE_MessageFlags flags) | ||
111 | { | ||
112 | struct FragmentClosure *fcls = cls; | ||
113 | struct GNUNET_MULTICAST_MessageHeader *msg1 = fcls->msg[fcls->n]; | ||
114 | uint64_t flags1 = fcls->flags[fcls->n++]; | ||
115 | int ret; | ||
116 | |||
117 | if (flags1 == flags && msg1->header.size == msg2->header.size | ||
118 | && 0 == memcmp (msg1, msg2, ntohs (msg1->header.size))) | ||
119 | { | ||
120 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Fragment %llu matches\n", | ||
121 | msg1->fragment_id); | ||
122 | ret = GNUNET_YES; | ||
123 | } | ||
124 | else | ||
125 | { | ||
126 | LOG (GNUNET_ERROR_TYPE_ERROR, "Fragment %llu differs\n", | ||
127 | msg1->fragment_id); | ||
128 | ret = GNUNET_SYSERR; | ||
129 | } | ||
130 | |||
131 | GNUNET_free (msg2); | ||
132 | return ret; | ||
133 | } | ||
134 | |||
135 | |||
136 | struct StateClosure { | ||
137 | size_t n; | ||
138 | void *value[16]; | ||
139 | size_t value_size[16]; | ||
140 | }; | ||
141 | |||
142 | static int | ||
143 | state_cb (void *cls, const char *name, const void *value, size_t value_size) | ||
144 | { | ||
145 | struct StateClosure *scls = cls; | ||
146 | const void *val = scls->value[scls->n]; | ||
147 | size_t val_size = scls->value_size[scls->n++]; | ||
148 | |||
149 | return value_size == val_size && 0 == memcmp (value, val, val_size) | ||
150 | ? GNUNET_YES | ||
151 | : GNUNET_SYSERR; | ||
152 | } | ||
153 | |||
154 | |||
155 | static void | ||
156 | run (void *cls, char *const *args, const char *cfgfile, | ||
157 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
158 | { | ||
159 | struct GNUNET_PSYCSTORE_PluginFunctions *db; | ||
160 | |||
161 | ok = 1; | ||
162 | db = load_plugin (cfg); | ||
163 | if (NULL == db) | ||
164 | { | ||
165 | FPRINTF (stderr, | ||
166 | "%s", | ||
167 | "Failed to initialize PSYCstore. " | ||
168 | "Database likely not setup, skipping test.\n"); | ||
169 | return; | ||
170 | } | ||
171 | |||
172 | /* Membership */ | ||
173 | |||
174 | channel_key = GNUNET_CRYPTO_ecc_key_create (); | ||
175 | slave_key = GNUNET_CRYPTO_ecc_key_create (); | ||
176 | |||
177 | GNUNET_CRYPTO_ecc_key_get_public (channel_key, &channel_pub_key); | ||
178 | GNUNET_CRYPTO_ecc_key_get_public (slave_key, &slave_pub_key); | ||
179 | |||
180 | ASSERT (GNUNET_OK == db->membership_store(db->cls, &channel_pub_key, | ||
181 | &slave_pub_key, GNUNET_YES, | ||
182 | 4, 2, 1)); | ||
183 | |||
184 | ASSERT (GNUNET_YES == db->membership_test(db->cls, &channel_pub_key, | ||
185 | &slave_pub_key, 4)); | ||
186 | |||
187 | ASSERT (GNUNET_YES == db->membership_test(db->cls, &channel_pub_key, | ||
188 | &slave_pub_key, 2)); | ||
189 | |||
190 | ASSERT (GNUNET_NO == db->membership_test(db->cls, &channel_pub_key, | ||
191 | &slave_pub_key, 1)); | ||
192 | |||
193 | |||
194 | /* Messages */ | ||
195 | |||
196 | struct GNUNET_MULTICAST_MessageHeader *msg | ||
197 | = GNUNET_malloc (sizeof (*msg) + sizeof (channel_pub_key)); | ||
198 | ASSERT (msg != NULL); | ||
199 | |||
200 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE); | ||
201 | msg->header.size = htons (sizeof (*msg) + sizeof (channel_pub_key)); | ||
202 | |||
203 | msg->hop_counter = 9; | ||
204 | msg->fragment_id = INT64_MAX - 1; | ||
205 | msg->fragment_offset = 0; | ||
206 | msg->message_id = INT64_MAX - 2; | ||
207 | msg->group_generation = INT64_MAX - 3; | ||
208 | msg->flags = GNUNET_MULTICAST_MESSAGE_LAST_FRAGMENT; | ||
209 | |||
210 | memcpy (&msg[1], &channel_pub_key, sizeof (channel_pub_key)); | ||
211 | |||
212 | msg->purpose.size = htonl (ntohs (msg->header.size) | ||
213 | - sizeof (msg->header) | ||
214 | - sizeof (msg->hop_counter) | ||
215 | - sizeof (msg->signature)); | ||
216 | msg->purpose.purpose = htonl (234); | ||
217 | GNUNET_CRYPTO_ecc_sign (slave_key, &msg->purpose, &msg->signature); | ||
218 | |||
219 | struct FragmentClosure fcls = { 0 }; | ||
220 | fcls.n = 0; | ||
221 | fcls.msg[0] = msg; | ||
222 | fcls.flags[0] = GNUNET_PSYCSTORE_MESSAGE_STATE; | ||
223 | |||
224 | ASSERT (GNUNET_OK == db->fragment_store (db->cls, &channel_pub_key, msg, | ||
225 | fcls.flags[0])); | ||
226 | |||
227 | ASSERT (GNUNET_OK == db->fragment_get (db->cls, &channel_pub_key, | ||
228 | msg->fragment_id, | ||
229 | fragment_cb, &fcls)); | ||
230 | ASSERT (fcls.n == 1); | ||
231 | |||
232 | fcls.n = 0; | ||
233 | |||
234 | ASSERT (GNUNET_OK == db->message_get_fragment (db->cls, &channel_pub_key, | ||
235 | msg->message_id, | ||
236 | msg->fragment_offset, | ||
237 | fragment_cb, &fcls)); | ||
238 | ASSERT (fcls.n == 1); | ||
239 | |||
240 | ASSERT (GNUNET_OK == db->message_add_flags ( | ||
241 | db->cls, &channel_pub_key, msg->message_id, | ||
242 | GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED)); | ||
243 | |||
244 | fcls.n = 0; | ||
245 | fcls.flags[0] |= GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED; | ||
246 | |||
247 | ASSERT (GNUNET_OK == db->fragment_get (db->cls, &channel_pub_key, | ||
248 | msg->fragment_id, | ||
249 | fragment_cb, &fcls)); | ||
250 | ASSERT (fcls.n == 1); | ||
251 | |||
252 | struct GNUNET_MULTICAST_MessageHeader *msg1 | ||
253 | = GNUNET_malloc (sizeof (*msg1) + sizeof (channel_pub_key)); | ||
254 | |||
255 | memcpy (msg1, msg, sizeof (*msg1) + sizeof (channel_pub_key)); | ||
256 | |||
257 | msg1->fragment_id++; | ||
258 | msg1->fragment_offset += 32768; | ||
259 | |||
260 | fcls.n = 0; | ||
261 | fcls.msg[1] = msg1; | ||
262 | fcls.flags[1] = GNUNET_PSYCSTORE_MESSAGE_STATE_HASH; | ||
263 | |||
264 | ASSERT (GNUNET_OK == db->fragment_store (db->cls, &channel_pub_key, msg1, | ||
265 | fcls.flags[1])); | ||
266 | |||
267 | ASSERT (GNUNET_OK == db->message_get (db->cls, &channel_pub_key, | ||
268 | msg->message_id, | ||
269 | fragment_cb, &fcls)); | ||
270 | ASSERT (fcls.n == 2); | ||
271 | |||
272 | uint64_t max_state_msg_id = 0; | ||
273 | ASSERT (GNUNET_OK == db->counters_get_slave (db->cls, &channel_pub_key, | ||
274 | &max_state_msg_id) | ||
275 | && max_state_msg_id == msg->message_id); | ||
276 | |||
277 | uint64_t fragment_id = 0, message_id = 0, group_generation = 0; | ||
278 | ASSERT (GNUNET_OK == db->counters_get_master (db->cls, &channel_pub_key, | ||
279 | &fragment_id, &message_id, | ||
280 | &group_generation) | ||
281 | && fragment_id == msg1->fragment_id | ||
282 | && message_id == msg1->message_id | ||
283 | && group_generation == msg1->group_generation); | ||
284 | |||
285 | |||
286 | /* State */ | ||
287 | |||
288 | ASSERT (GNUNET_OK == db->state_set (db->cls, &channel_pub_key, "_foo", | ||
289 | C2ARG("one two three"))); | ||
290 | |||
291 | ASSERT (GNUNET_OK == db->state_set (db->cls, &channel_pub_key, "_foo_bar", | ||
292 | slave_key, | ||
293 | sizeof (*slave_key))); | ||
294 | |||
295 | struct StateClosure scls = { 0 }; | ||
296 | scls.n = 0; | ||
297 | scls.value[0] = "one two three"; | ||
298 | scls.value_size[0] = strlen ("one two three"); | ||
299 | |||
300 | ASSERT (GNUNET_OK == db->state_get (db->cls, &channel_pub_key, "_foo", | ||
301 | state_cb, &scls)); | ||
302 | ASSERT (scls.n == 1); | ||
303 | |||
304 | scls.n = 0; | ||
305 | scls.value[1] = slave_key; | ||
306 | scls.value_size[1] = sizeof (*slave_key); | ||
307 | |||
308 | ASSERT (GNUNET_OK == db->state_get_all (db->cls, &channel_pub_key, "_foo", | ||
309 | state_cb, &scls)); | ||
310 | ASSERT (scls.n == 2); | ||
311 | |||
312 | scls.n = 0; | ||
313 | ASSERT (GNUNET_NO == db->state_get_signed (db->cls, &channel_pub_key, | ||
314 | state_cb, &scls)); | ||
315 | ASSERT (scls.n == 0); | ||
316 | |||
317 | ASSERT (GNUNET_OK == db->state_update_signed (db->cls, &channel_pub_key)); | ||
318 | |||
319 | scls.n = 0; | ||
320 | ASSERT (GNUNET_YES == db->state_get_signed (db->cls, &channel_pub_key, | ||
321 | state_cb, &scls)); | ||
322 | ASSERT (scls.n == 2); | ||
323 | |||
324 | ok = 0; | ||
325 | |||
326 | FAILURE: | ||
327 | |||
328 | if (NULL != channel_key) | ||
329 | { | ||
330 | GNUNET_free (channel_key); | ||
331 | channel_key = NULL; | ||
332 | } | ||
333 | if (NULL != slave_key) | ||
334 | { | ||
335 | GNUNET_free (slave_key); | ||
336 | slave_key = NULL; | ||
337 | } | ||
338 | |||
339 | unload_plugin (db); | ||
340 | } | ||
341 | |||
342 | |||
343 | int | ||
344 | main (int argc, char *argv[]) | ||
345 | { | ||
346 | char cfg_name[128]; | ||
347 | char *const xargv[] = { | ||
348 | "test-plugin-psycstore", | ||
349 | "-c", cfg_name, | ||
350 | "-L", LOG_LEVEL, | ||
351 | NULL | ||
352 | }; | ||
353 | struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
354 | GNUNET_GETOPT_OPTION_END | ||
355 | }; | ||
356 | |||
357 | GNUNET_DISK_directory_remove ("/tmp/gnunet-test-plugin-psycstore-sqlite"); | ||
358 | GNUNET_log_setup ("test-plugin-psycstore", LOG_LEVEL, NULL); | ||
359 | plugin_name = GNUNET_TESTING_get_testname_from_underscore (argv[0]); | ||
360 | GNUNET_snprintf (cfg_name, sizeof (cfg_name), "test_plugin_psycstore_%s.conf", | ||
361 | plugin_name); | ||
362 | GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1, xargv, | ||
363 | "test-plugin-psycstore", "nohelp", options, &run, NULL); | ||
364 | |||
365 | if (ok != 0) | ||
366 | FPRINTF (stderr, "Missed some testcases: %d\n", ok); | ||
367 | |||
368 | #if ! DEBUG_PSYCSTORE | ||
369 | GNUNET_DISK_directory_remove ("/tmp/gnunet-test-plugin-psycstore-sqlite"); | ||
370 | #endif | ||
371 | |||
372 | return ok; | ||
373 | } | ||
374 | |||
375 | /* end of test_plugin_psycstore.c */ | ||