diff options
Diffstat (limited to 'src/service/datastore/test_datastore_api.c')
-rw-r--r-- | src/service/datastore/test_datastore_api.c | 732 |
1 files changed, 732 insertions, 0 deletions
diff --git a/src/service/datastore/test_datastore_api.c b/src/service/datastore/test_datastore_api.c new file mode 100644 index 000000000..58a6b7a28 --- /dev/null +++ b/src/service/datastore/test_datastore_api.c | |||
@@ -0,0 +1,732 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2004, 2005, 2006, 2007, 2009, 2015 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your 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 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /* | ||
21 | * @file datastore/test_datastore_api.c | ||
22 | * @brief Test for the basic datastore API. | ||
23 | * @author Christian Grothoff | ||
24 | * | ||
25 | * TODO: | ||
26 | * - test reservation failure | ||
27 | */ | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_util_lib.h" | ||
31 | #include "gnunet_protocols.h" | ||
32 | #include "gnunet_datastore_service.h" | ||
33 | #include "gnunet_datastore_plugin.h" | ||
34 | #include "gnunet_testing_lib.h" | ||
35 | |||
36 | |||
37 | /** | ||
38 | * How long until we give up on transmitting the message? | ||
39 | */ | ||
40 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15) | ||
41 | |||
42 | #define ITERATIONS 256 | ||
43 | |||
44 | /** | ||
45 | * Handle to the datastore. | ||
46 | */ | ||
47 | static struct GNUNET_DATASTORE_Handle *datastore; | ||
48 | |||
49 | static struct GNUNET_TIME_Absolute now; | ||
50 | |||
51 | /** | ||
52 | * Value we return from #main(). | ||
53 | */ | ||
54 | static int ok; | ||
55 | |||
56 | /** | ||
57 | * Name of plugin under test. | ||
58 | */ | ||
59 | static const char *plugin_name; | ||
60 | |||
61 | |||
62 | static size_t | ||
63 | get_size (int i) | ||
64 | { | ||
65 | return 8 * i; | ||
66 | } | ||
67 | |||
68 | |||
69 | static const void * | ||
70 | get_data (int i) | ||
71 | { | ||
72 | static char buf[60000]; | ||
73 | |||
74 | memset (buf, i, 8 * i); | ||
75 | return buf; | ||
76 | } | ||
77 | |||
78 | |||
79 | static int | ||
80 | get_type (int i) | ||
81 | { | ||
82 | return i + 1; | ||
83 | } | ||
84 | |||
85 | |||
86 | static int | ||
87 | get_priority (int i) | ||
88 | { | ||
89 | return i + 1; | ||
90 | } | ||
91 | |||
92 | |||
93 | static int | ||
94 | get_anonymity (int i) | ||
95 | { | ||
96 | return i; | ||
97 | } | ||
98 | |||
99 | |||
100 | static struct GNUNET_TIME_Absolute | ||
101 | get_expiration (int i) | ||
102 | { | ||
103 | struct GNUNET_TIME_Absolute av; | ||
104 | |||
105 | av.abs_value_us = now.abs_value_us + 20000000000LL - i * 1000 * 1000LL; | ||
106 | return av; | ||
107 | } | ||
108 | |||
109 | |||
110 | /** | ||
111 | * Which phase of the process are we in? | ||
112 | */ | ||
113 | enum RunPhase | ||
114 | { | ||
115 | /** | ||
116 | * We are done (shutting down normally). | ||
117 | */ | ||
118 | RP_DONE = 0, | ||
119 | |||
120 | /** | ||
121 | * We are adding new entries to the datastore. | ||
122 | */ | ||
123 | RP_PUT = 1, | ||
124 | RP_GET = 2, | ||
125 | RP_DEL = 3, | ||
126 | RP_DO_DEL = 4, | ||
127 | RP_DELVALIDATE = 5, | ||
128 | RP_RESERVE = 6, | ||
129 | RP_PUT_MULTIPLE = 7, | ||
130 | RP_PUT_MULTIPLE_NEXT = 8, | ||
131 | RP_GET_MULTIPLE = 9, | ||
132 | RP_GET_MULTIPLE_NEXT = 10, | ||
133 | |||
134 | /** | ||
135 | * Execution failed with some kind of error. | ||
136 | */ | ||
137 | RP_ERROR | ||
138 | }; | ||
139 | |||
140 | |||
141 | /** | ||
142 | * Closure we give to all of the functions executing the | ||
143 | * benchmark. Could right now be global, but this allows | ||
144 | * us to theoretically run multiple clients "in parallel". | ||
145 | */ | ||
146 | struct CpsRunContext | ||
147 | { | ||
148 | /** | ||
149 | * Execution phase we are in. | ||
150 | */ | ||
151 | enum RunPhase phase; | ||
152 | |||
153 | struct GNUNET_HashCode key; | ||
154 | int i; | ||
155 | int rid; | ||
156 | void *data; | ||
157 | size_t size; | ||
158 | |||
159 | uint64_t first_uid; | ||
160 | }; | ||
161 | |||
162 | |||
163 | /** | ||
164 | * Main state machine. Executes the next step of the test | ||
165 | * depending on the current state. | ||
166 | * | ||
167 | * @param cls the `struct CpsRunContext` | ||
168 | */ | ||
169 | static void | ||
170 | run_continuation (void *cls); | ||
171 | |||
172 | |||
173 | /** | ||
174 | * Continuation called to notify client about result of an | ||
175 | * operation. Checks for errors, updates our iteration counters and | ||
176 | * continues execution with #run_continuation(). | ||
177 | * | ||
178 | * @param cls the `struct CpsRunContext` | ||
179 | * @param success #GNUNET_SYSERR on failure | ||
180 | * @param min_expiration minimum expiration time required for content to be stored | ||
181 | * by the datacache at this time, zero for unknown | ||
182 | * @param msg NULL on success, otherwise an error message | ||
183 | */ | ||
184 | static void | ||
185 | check_success (void *cls, | ||
186 | int success, | ||
187 | struct GNUNET_TIME_Absolute min_expiration, | ||
188 | const char *msg) | ||
189 | { | ||
190 | struct CpsRunContext *crc = cls; | ||
191 | |||
192 | if (GNUNET_OK != success) | ||
193 | { | ||
194 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
195 | "Operation %d/%d not successful: `%s'\n", | ||
196 | crc->phase, | ||
197 | crc->i, | ||
198 | msg); | ||
199 | crc->phase = RP_ERROR; | ||
200 | } | ||
201 | GNUNET_free (crc->data); | ||
202 | crc->data = NULL; | ||
203 | GNUNET_SCHEDULER_add_now (&run_continuation, crc); | ||
204 | } | ||
205 | |||
206 | |||
207 | static void | ||
208 | get_reserved (void *cls, | ||
209 | int success, | ||
210 | struct GNUNET_TIME_Absolute min_expiration, | ||
211 | const char *msg) | ||
212 | { | ||
213 | struct CpsRunContext *crc = cls; | ||
214 | |||
215 | if (0 >= success) | ||
216 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
217 | "Error obtaining reservation: `%s'\n", | ||
218 | msg); | ||
219 | GNUNET_assert (0 < success); | ||
220 | crc->rid = success; | ||
221 | GNUNET_SCHEDULER_add_now (&run_continuation, | ||
222 | crc); | ||
223 | } | ||
224 | |||
225 | |||
226 | static void | ||
227 | check_value (void *cls, | ||
228 | const struct GNUNET_HashCode *key, | ||
229 | size_t size, | ||
230 | const void *data, | ||
231 | enum GNUNET_BLOCK_Type type, | ||
232 | uint32_t priority, | ||
233 | uint32_t anonymity, | ||
234 | uint32_t replication, | ||
235 | struct GNUNET_TIME_Absolute expiration, | ||
236 | uint64_t uid) | ||
237 | { | ||
238 | struct CpsRunContext *crc = cls; | ||
239 | int i; | ||
240 | |||
241 | i = crc->i; | ||
242 | if (NULL == key) | ||
243 | { | ||
244 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
245 | "Value check failed (got NULL key) in %d/%d\n", | ||
246 | crc->phase, | ||
247 | crc->i); | ||
248 | crc->phase = RP_ERROR; | ||
249 | GNUNET_SCHEDULER_add_now (&run_continuation, | ||
250 | crc); | ||
251 | return; | ||
252 | } | ||
253 | #if 0 | ||
254 | fprintf (stderr, | ||
255 | "Check value got `%s' of size %u, type %d, expire %s\n", | ||
256 | GNUNET_h2s (key), (unsigned int) size, type, | ||
257 | GNUNET_STRINGS_absolute_time_to_string (expiration)); | ||
258 | fprintf (stderr, | ||
259 | "Check value iteration %d wants size %u, type %d, expire %s\n", i, | ||
260 | (unsigned int) get_size (i), get_type (i), | ||
261 | GNUNET_STRINGS_absolute_time_to_string (get_expiration (i))); | ||
262 | #endif | ||
263 | GNUNET_assert (size == get_size (i)); | ||
264 | GNUNET_assert (0 == memcmp (data, get_data (i), size)); | ||
265 | GNUNET_assert (type == get_type (i)); | ||
266 | GNUNET_assert (priority == get_priority (i)); | ||
267 | GNUNET_assert (anonymity == get_anonymity (i)); | ||
268 | GNUNET_assert (expiration.abs_value_us == get_expiration (i).abs_value_us); | ||
269 | if (crc->i == 0) | ||
270 | { | ||
271 | crc->phase = RP_DEL; | ||
272 | crc->i = ITERATIONS; | ||
273 | } | ||
274 | GNUNET_SCHEDULER_add_now (&run_continuation, | ||
275 | crc); | ||
276 | } | ||
277 | |||
278 | |||
279 | static void | ||
280 | delete_value (void *cls, | ||
281 | const struct GNUNET_HashCode *key, | ||
282 | size_t size, | ||
283 | const void *data, | ||
284 | enum GNUNET_BLOCK_Type type, | ||
285 | uint32_t priority, | ||
286 | uint32_t anonymity, | ||
287 | uint32_t replication, | ||
288 | struct GNUNET_TIME_Absolute expiration, | ||
289 | uint64_t uid) | ||
290 | { | ||
291 | struct CpsRunContext *crc = cls; | ||
292 | |||
293 | GNUNET_assert (NULL == crc->data); | ||
294 | GNUNET_assert (NULL != key); | ||
295 | crc->size = size; | ||
296 | crc->key = *key; | ||
297 | crc->data = GNUNET_malloc (size); | ||
298 | GNUNET_memcpy (crc->data, data, size); | ||
299 | crc->phase = RP_DO_DEL; | ||
300 | GNUNET_SCHEDULER_add_now (&run_continuation, | ||
301 | crc); | ||
302 | } | ||
303 | |||
304 | |||
305 | static void | ||
306 | check_nothing (void *cls, | ||
307 | const struct GNUNET_HashCode *key, | ||
308 | size_t size, | ||
309 | const void *data, | ||
310 | enum GNUNET_BLOCK_Type type, | ||
311 | uint32_t priority, | ||
312 | uint32_t anonymity, | ||
313 | uint32_t replication, | ||
314 | struct GNUNET_TIME_Absolute expiration, | ||
315 | uint64_t uid) | ||
316 | { | ||
317 | struct CpsRunContext *crc = cls; | ||
318 | |||
319 | GNUNET_assert (key == NULL); | ||
320 | if (crc->i == 0) | ||
321 | crc->phase = RP_RESERVE; | ||
322 | GNUNET_SCHEDULER_add_now (&run_continuation, | ||
323 | crc); | ||
324 | } | ||
325 | |||
326 | |||
327 | static void | ||
328 | check_multiple (void *cls, | ||
329 | const struct GNUNET_HashCode *key, | ||
330 | size_t size, | ||
331 | const void *data, | ||
332 | enum GNUNET_BLOCK_Type type, | ||
333 | uint32_t priority, | ||
334 | uint32_t anonymity, | ||
335 | uint32_t replication, | ||
336 | struct GNUNET_TIME_Absolute expiration, | ||
337 | uint64_t uid) | ||
338 | { | ||
339 | struct CpsRunContext *crc = cls; | ||
340 | |||
341 | GNUNET_assert (key != NULL); | ||
342 | switch (crc->phase) | ||
343 | { | ||
344 | case RP_GET_MULTIPLE: | ||
345 | crc->phase = RP_GET_MULTIPLE_NEXT; | ||
346 | crc->first_uid = uid; | ||
347 | break; | ||
348 | |||
349 | case RP_GET_MULTIPLE_NEXT: | ||
350 | GNUNET_assert (uid != crc->first_uid); | ||
351 | crc->phase = RP_DONE; | ||
352 | break; | ||
353 | |||
354 | default: | ||
355 | GNUNET_break (0); | ||
356 | crc->phase = RP_ERROR; | ||
357 | break; | ||
358 | } | ||
359 | GNUNET_SCHEDULER_add_now (&run_continuation, crc); | ||
360 | } | ||
361 | |||
362 | |||
363 | /** | ||
364 | * Main state machine. Executes the next step of the test | ||
365 | * depending on the current state. | ||
366 | * | ||
367 | * @param cls the `struct CpsRunContext` | ||
368 | */ | ||
369 | static void | ||
370 | run_continuation (void *cls) | ||
371 | { | ||
372 | struct CpsRunContext *crc = cls; | ||
373 | |||
374 | ok = (int) crc->phase; | ||
375 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
376 | "Test in phase %u\n", | ||
377 | crc->phase); | ||
378 | switch (crc->phase) | ||
379 | { | ||
380 | case RP_PUT: | ||
381 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
382 | "Executing PUT number %u\n", | ||
383 | crc->i); | ||
384 | GNUNET_CRYPTO_hash (&crc->i, sizeof(int), &crc->key); | ||
385 | GNUNET_DATASTORE_put (datastore, 0, &crc->key, get_size (crc->i), | ||
386 | get_data (crc->i), get_type (crc->i), | ||
387 | get_priority (crc->i), get_anonymity (crc->i), 0, | ||
388 | get_expiration (crc->i), 1, 1, | ||
389 | &check_success, crc); | ||
390 | crc->i++; | ||
391 | if (crc->i == ITERATIONS) | ||
392 | crc->phase = RP_GET; | ||
393 | break; | ||
394 | |||
395 | case RP_GET: | ||
396 | crc->i--; | ||
397 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
398 | "Executing GET number %u\n", | ||
399 | crc->i); | ||
400 | GNUNET_CRYPTO_hash (&crc->i, | ||
401 | sizeof(int), | ||
402 | &crc->key); | ||
403 | GNUNET_DATASTORE_get_key (datastore, | ||
404 | 0, | ||
405 | false, | ||
406 | &crc->key, | ||
407 | get_type (crc->i), | ||
408 | 1, | ||
409 | 1, | ||
410 | &check_value, | ||
411 | crc); | ||
412 | break; | ||
413 | |||
414 | case RP_DEL: | ||
415 | crc->i--; | ||
416 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
417 | "Executing DEL number %u\n", | ||
418 | crc->i); | ||
419 | crc->data = NULL; | ||
420 | GNUNET_CRYPTO_hash (&crc->i, sizeof(int), &crc->key); | ||
421 | GNUNET_assert (NULL != | ||
422 | GNUNET_DATASTORE_get_key (datastore, | ||
423 | 0, | ||
424 | false, | ||
425 | &crc->key, | ||
426 | get_type (crc->i), | ||
427 | 1, | ||
428 | 1, | ||
429 | &delete_value, | ||
430 | crc)); | ||
431 | break; | ||
432 | |||
433 | case RP_DO_DEL: | ||
434 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
435 | "Executing DO_DEL number %u\n", | ||
436 | crc->i); | ||
437 | if (crc->i == 0) | ||
438 | { | ||
439 | crc->i = ITERATIONS; | ||
440 | crc->phase = RP_DELVALIDATE; | ||
441 | } | ||
442 | else | ||
443 | { | ||
444 | crc->phase = RP_DEL; | ||
445 | } | ||
446 | GNUNET_assert (NULL != | ||
447 | GNUNET_DATASTORE_remove (datastore, &crc->key, crc->size, | ||
448 | crc->data, 1, 1, | ||
449 | &check_success, crc)); | ||
450 | break; | ||
451 | |||
452 | case RP_DELVALIDATE: | ||
453 | crc->i--; | ||
454 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
455 | "Executing DELVALIDATE number %u\n", | ||
456 | crc->i); | ||
457 | GNUNET_CRYPTO_hash (&crc->i, sizeof(int), &crc->key); | ||
458 | GNUNET_assert (NULL != | ||
459 | GNUNET_DATASTORE_get_key (datastore, | ||
460 | 0, | ||
461 | false, | ||
462 | &crc->key, | ||
463 | get_type (crc->i), | ||
464 | 1, | ||
465 | 1, | ||
466 | &check_nothing, | ||
467 | crc)); | ||
468 | break; | ||
469 | |||
470 | case RP_RESERVE: | ||
471 | crc->phase = RP_PUT_MULTIPLE; | ||
472 | GNUNET_DATASTORE_reserve (datastore, 128 * 1024, 2, | ||
473 | &get_reserved, crc); | ||
474 | break; | ||
475 | |||
476 | case RP_PUT_MULTIPLE: | ||
477 | crc->phase = RP_PUT_MULTIPLE_NEXT; | ||
478 | GNUNET_DATASTORE_put (datastore, crc->rid, &crc->key, get_size (42), | ||
479 | get_data (42), get_type (42), get_priority (42), | ||
480 | get_anonymity (42), 0, get_expiration (42), 1, 1, | ||
481 | &check_success, crc); | ||
482 | break; | ||
483 | |||
484 | case RP_PUT_MULTIPLE_NEXT: | ||
485 | crc->phase = RP_GET_MULTIPLE; | ||
486 | GNUNET_DATASTORE_put (datastore, crc->rid, | ||
487 | &crc->key, | ||
488 | get_size (43), | ||
489 | get_data (43), | ||
490 | get_type (42), | ||
491 | get_priority (43), | ||
492 | get_anonymity (43), | ||
493 | 0, | ||
494 | get_expiration (43), | ||
495 | 1, 1, | ||
496 | &check_success, crc); | ||
497 | break; | ||
498 | |||
499 | case RP_GET_MULTIPLE: | ||
500 | GNUNET_assert (NULL != | ||
501 | GNUNET_DATASTORE_get_key (datastore, | ||
502 | 0, | ||
503 | false, | ||
504 | &crc->key, | ||
505 | get_type (42), | ||
506 | 1, | ||
507 | 1, | ||
508 | &check_multiple, | ||
509 | crc)); | ||
510 | break; | ||
511 | |||
512 | case RP_GET_MULTIPLE_NEXT: | ||
513 | GNUNET_assert (NULL != | ||
514 | GNUNET_DATASTORE_get_key (datastore, | ||
515 | crc->first_uid + 1, | ||
516 | false, | ||
517 | &crc->key, | ||
518 | get_type (42), | ||
519 | 1, | ||
520 | 1, | ||
521 | &check_multiple, | ||
522 | crc)); | ||
523 | break; | ||
524 | |||
525 | case RP_DONE: | ||
526 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
527 | "Finished, disconnecting\n"); | ||
528 | GNUNET_DATASTORE_disconnect (datastore, | ||
529 | GNUNET_YES); | ||
530 | GNUNET_free (crc); | ||
531 | ok = 0; | ||
532 | break; | ||
533 | |||
534 | case RP_ERROR: | ||
535 | GNUNET_DATASTORE_disconnect (datastore, | ||
536 | GNUNET_YES); | ||
537 | GNUNET_free (crc); | ||
538 | ok = 43; | ||
539 | break; | ||
540 | } | ||
541 | } | ||
542 | |||
543 | |||
544 | /** | ||
545 | * Function called with the result of the initial PUT operation. If | ||
546 | * the PUT succeeded, we start the actual benchmark loop, otherwise we | ||
547 | * bail out with an error. | ||
548 | * | ||
549 | * | ||
550 | * @param cls closure | ||
551 | * @param success #GNUNET_SYSERR on failure | ||
552 | * @param min_expiration minimum expiration time required for content to be stored | ||
553 | * by the datacache at this time, zero for unknown | ||
554 | * @param msg NULL on success, otherwise an error message | ||
555 | */ | ||
556 | static void | ||
557 | run_tests (void *cls, | ||
558 | int32_t success, | ||
559 | struct GNUNET_TIME_Absolute min_expiration, | ||
560 | const char *msg) | ||
561 | { | ||
562 | struct CpsRunContext *crc = cls; | ||
563 | |||
564 | switch (success) | ||
565 | { | ||
566 | case GNUNET_YES: | ||
567 | GNUNET_SCHEDULER_add_now (&run_continuation, | ||
568 | crc); | ||
569 | return; | ||
570 | |||
571 | case GNUNET_NO: | ||
572 | fprintf (stderr, | ||
573 | "%s", "Test 'put' operation failed, key already exists (!?)\n"); | ||
574 | GNUNET_DATASTORE_disconnect (datastore, | ||
575 | GNUNET_YES); | ||
576 | GNUNET_free (crc); | ||
577 | return; | ||
578 | |||
579 | case GNUNET_SYSERR: | ||
580 | fprintf (stderr, | ||
581 | "Test 'put' operation failed with error `%s' database likely not setup, skipping test.\n", | ||
582 | msg); | ||
583 | GNUNET_DATASTORE_disconnect (datastore, | ||
584 | GNUNET_YES); | ||
585 | GNUNET_free (crc); | ||
586 | return; | ||
587 | |||
588 | default: | ||
589 | GNUNET_assert (0); | ||
590 | } | ||
591 | } | ||
592 | |||
593 | |||
594 | /** | ||
595 | * Beginning of the actual execution of the benchmark. | ||
596 | * Performs a first test operation (PUT) to verify that | ||
597 | * the plugin works at all. | ||
598 | * | ||
599 | * @param cls NULL | ||
600 | * @param cfg configuration to use | ||
601 | * @param peer peer handle (unused) | ||
602 | */ | ||
603 | static void | ||
604 | run (void *cls, | ||
605 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
606 | struct GNUNET_TESTING_Peer *peer) | ||
607 | { | ||
608 | struct CpsRunContext *crc; | ||
609 | static struct GNUNET_HashCode zkey; | ||
610 | |||
611 | crc = GNUNET_new (struct CpsRunContext); | ||
612 | crc->phase = RP_PUT; | ||
613 | now = GNUNET_TIME_absolute_get (); | ||
614 | datastore = GNUNET_DATASTORE_connect (cfg); | ||
615 | if (NULL == | ||
616 | GNUNET_DATASTORE_put (datastore, | ||
617 | 0, | ||
618 | &zkey, | ||
619 | 4, | ||
620 | "TEST", | ||
621 | GNUNET_BLOCK_TYPE_TEST, | ||
622 | 0, 0, 0, | ||
623 | GNUNET_TIME_relative_to_absolute | ||
624 | (GNUNET_TIME_UNIT_SECONDS), | ||
625 | 0, 1, | ||
626 | &run_tests, crc)) | ||
627 | { | ||
628 | fprintf (stderr, | ||
629 | "%s", | ||
630 | "Test 'put' operation failed.\n"); | ||
631 | ok = 1; | ||
632 | GNUNET_free (crc); | ||
633 | } | ||
634 | } | ||
635 | |||
636 | |||
637 | /** | ||
638 | * Function invoked to notify service of disk utilization | ||
639 | * changes. | ||
640 | * | ||
641 | * @param cls closure | ||
642 | * @param delta change in disk utilization, | ||
643 | * 0 for "reset to empty" | ||
644 | */ | ||
645 | static void | ||
646 | duc_dummy (void *cls, | ||
647 | int delta) | ||
648 | { | ||
649 | /* intentionally empty */ | ||
650 | } | ||
651 | |||
652 | |||
653 | /** | ||
654 | * check if plugin is actually working | ||
655 | */ | ||
656 | static int | ||
657 | test_plugin (const char *cfg_name) | ||
658 | { | ||
659 | char libname[128]; | ||
660 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
661 | struct GNUNET_DATASTORE_PluginFunctions *api; | ||
662 | struct GNUNET_DATASTORE_PluginEnvironment env; | ||
663 | |||
664 | cfg = GNUNET_CONFIGURATION_create (); | ||
665 | if (GNUNET_OK != | ||
666 | GNUNET_CONFIGURATION_load (cfg, | ||
667 | cfg_name)) | ||
668 | { | ||
669 | GNUNET_CONFIGURATION_destroy (cfg); | ||
670 | fprintf (stderr, | ||
671 | "Failed to load configuration %s\n", | ||
672 | cfg_name); | ||
673 | return 1; | ||
674 | } | ||
675 | memset (&env, 0, sizeof(env)); | ||
676 | env.cfg = cfg; | ||
677 | env.duc = &duc_dummy; | ||
678 | GNUNET_snprintf (libname, | ||
679 | sizeof(libname), | ||
680 | "libgnunet_plugin_datastore_%s", | ||
681 | plugin_name); | ||
682 | api = GNUNET_PLUGIN_load (libname, &env); | ||
683 | if (NULL == api) | ||
684 | { | ||
685 | GNUNET_CONFIGURATION_destroy (cfg); | ||
686 | fprintf (stderr, | ||
687 | "Failed to load plugin `%s'\n", | ||
688 | libname); | ||
689 | return 77; | ||
690 | } | ||
691 | GNUNET_PLUGIN_unload (libname, api); | ||
692 | GNUNET_CONFIGURATION_destroy (cfg); | ||
693 | return 0; | ||
694 | } | ||
695 | |||
696 | |||
697 | /** | ||
698 | * Entry point into the test. Determines which configuration / plugin | ||
699 | * we are running with based on the name of the binary and starts | ||
700 | * the peer. | ||
701 | * | ||
702 | * @param argc should be 1 | ||
703 | * @param argv used to determine plugin / configuration name. | ||
704 | * @return 0 on success | ||
705 | */ | ||
706 | int | ||
707 | main (int argc, | ||
708 | char *argv[]) | ||
709 | { | ||
710 | char cfg_name[PATH_MAX]; | ||
711 | int ret; | ||
712 | |||
713 | plugin_name = GNUNET_STRINGS_get_suffix_from_binary_name (argv[0]); | ||
714 | GNUNET_snprintf (cfg_name, | ||
715 | sizeof(cfg_name), | ||
716 | "test_datastore_api_data_%s.conf", | ||
717 | plugin_name); | ||
718 | ret = test_plugin (cfg_name); | ||
719 | if (0 != ret) | ||
720 | return ret; | ||
721 | /* run actual test */ | ||
722 | if (0 != | ||
723 | GNUNET_TESTING_peer_run ("test-gnunet-datastore", | ||
724 | cfg_name, | ||
725 | &run, | ||
726 | NULL)) | ||
727 | return 1; | ||
728 | return ok; | ||
729 | } | ||
730 | |||
731 | |||
732 | /* end of test_datastore_api.c */ | ||