aboutsummaryrefslogtreecommitdiff
path: root/src/datastore
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2009-07-25 14:30:10 +0000
committerChristian Grothoff <christian@grothoff.org>2009-07-25 14:30:10 +0000
commit4f3705cbfef52322292ce8b60f1d5326825f8606 (patch)
treed46c3294cb791d674ab63829d3559c9a162404f1 /src/datastore
parenta8871b8ff983bdb8adc224a9a88ba5d2960df859 (diff)
downloadgnunet-4f3705cbfef52322292ce8b60f1d5326825f8606.tar.gz
gnunet-4f3705cbfef52322292ce8b60f1d5326825f8606.zip
more tests
Diffstat (limited to 'src/datastore')
-rw-r--r--src/datastore/Makefile.am7
-rw-r--r--src/datastore/datastore.h2
-rw-r--r--src/datastore/datastore_api.c13
-rw-r--r--src/datastore/gnunet-service-datastore.c8
-rw-r--r--src/datastore/plugin_datastore_sqlite.c8
-rw-r--r--src/datastore/test_datastore_api.c189
-rw-r--r--src/datastore/test_datastore_api_management.c377
7 files changed, 580 insertions, 24 deletions
diff --git a/src/datastore/Makefile.am b/src/datastore/Makefile.am
index 17fdb4378..07a14e534 100644
--- a/src/datastore/Makefile.am
+++ b/src/datastore/Makefile.am
@@ -58,6 +58,7 @@ libgnunet_plugin_datastore_template_la_LDFLAGS = \
58 58
59check_PROGRAMS = \ 59check_PROGRAMS = \
60 test_datastore_api \ 60 test_datastore_api \
61 test_datastore_api_management \
61 perf_datastore_api \ 62 perf_datastore_api \
62 perf_plugin_datastore 63 perf_plugin_datastore
63 64
@@ -69,6 +70,12 @@ test_datastore_api_LDADD = \
69 $(top_builddir)/src/datastore/libgnunetdatastore.la \ 70 $(top_builddir)/src/datastore/libgnunetdatastore.la \
70 $(top_builddir)/src/util/libgnunetutil.la 71 $(top_builddir)/src/util/libgnunetutil.la
71 72
73test_datastore_api_management_SOURCES = \
74 test_datastore_api_management.c
75test_datastore_api_management_LDADD = \
76 $(top_builddir)/src/datastore/libgnunetdatastore.la \
77 $(top_builddir)/src/util/libgnunetutil.la
78
72perf_datastore_api_SOURCES = \ 79perf_datastore_api_SOURCES = \
73 perf_datastore_api.c 80 perf_datastore_api.c
74perf_datastore_api_LDADD = \ 81perf_datastore_api_LDADD = \
diff --git a/src/datastore/datastore.h b/src/datastore/datastore.h
index f1da17ee4..aa2646c0a 100644
--- a/src/datastore/datastore.h
+++ b/src/datastore/datastore.h
@@ -19,7 +19,7 @@
19*/ 19*/
20 20
21/** 21/**
22 * @file datastore/datastore.hc 22 * @file datastore/datastore.h
23 * @brief structs for communication between datastore service and API 23 * @brief structs for communication between datastore service and API
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 */ 25 */
diff --git a/src/datastore/datastore_api.c b/src/datastore/datastore_api.c
index f9a28800c..361f76e4a 100644
--- a/src/datastore/datastore_api.c
+++ b/src/datastore/datastore_api.c
@@ -204,16 +204,21 @@ with_status_response_handler (void *cls,
204 sm = (const struct StatusMessage*) msg; 204 sm = (const struct StatusMessage*) msg;
205 status = ntohl(sm->status); 205 status = ntohl(sm->status);
206 emsg = NULL; 206 emsg = NULL;
207 if (status == GNUNET_SYSERR) 207 if (ntohs(msg->size) > sizeof(struct StatusMessage))
208 { 208 {
209 emsg = (const char*) &sm[1]; 209 emsg = (const char*) &sm[1];
210 if ( (ntohs(msg->size) == sizeof(struct StatusMessage)) || 210 if (emsg[ntohs(msg->size) - sizeof(struct StatusMessage) - 1] != '\0')
211 (emsg[ntohs(msg->size) - sizeof(struct StatusMessage) - 1] != '\0') )
212 { 211 {
213 GNUNET_break (0); 212 GNUNET_break (0);
214 emsg = _("Invalid error message received from datastore service"); 213 emsg = _("Invalid error message received from datastore service");
215 } 214 }
216 } 215 }
216 if ( (status == GNUNET_SYSERR) &&
217 (emsg == NULL) )
218 {
219 GNUNET_break (0);
220 emsg = _("Invalid error message received from datastore service");
221 }
217 h->response_proc = NULL; 222 h->response_proc = NULL;
218#if DEBUG_DATASTORE 223#if DEBUG_DATASTORE
219 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 224 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -408,7 +413,7 @@ GNUNET_DATASTORE_reserve (struct GNUNET_DATASTORE_Handle *h,
408 rm->header.type = htons(GNUNET_MESSAGE_TYPE_DATASTORE_RESERVE); 413 rm->header.type = htons(GNUNET_MESSAGE_TYPE_DATASTORE_RESERVE);
409 rm->header.size = htons(sizeof (struct ReserveMessage)); 414 rm->header.size = htons(sizeof (struct ReserveMessage));
410 rm->entries = htonl(entries); 415 rm->entries = htonl(entries);
411 rm->amount = htonl(amount); 416 rm->amount = GNUNET_htonll(amount);
412 transmit_for_status (h, cont, cont_cls, timeout); 417 transmit_for_status (h, cont, cont_cls, timeout);
413} 418}
414 419
diff --git a/src/datastore/gnunet-service-datastore.c b/src/datastore/gnunet-service-datastore.c
index 77047dc8a..22ae6feb5 100644
--- a/src/datastore/gnunet-service-datastore.c
+++ b/src/datastore/gnunet-service-datastore.c
@@ -513,7 +513,7 @@ transmit_status (struct GNUNET_SERVER_Client *client,
513 513
514#if DEBUG_DATASTORE 514#if DEBUG_DATASTORE
515 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 515 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
516 "Transmitting `%s' message with value %d and message %s\n", 516 "Transmitting `%s' message with value %d and message `%s'\n",
517 "STATUS", 517 "STATUS",
518 code, 518 code,
519 msg != NULL ? msg : "(none)"); 519 msg != NULL ? msg : "(none)");
@@ -639,15 +639,15 @@ handle_reserve (void *cls,
639 unsigned long long used; 639 unsigned long long used;
640 unsigned long long req; 640 unsigned long long req;
641 uint64_t amount; 641 uint64_t amount;
642 uint64_t entries; 642 uint32_t entries;
643 643
644#if DEBUG_DATASTORE 644#if DEBUG_DATASTORE
645 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 645 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
646 "Processing `%s' request\n", 646 "Processing `%s' request\n",
647 "RESERVE"); 647 "RESERVE");
648#endif 648#endif
649 amount = ntohl(msg->amount); 649 amount = GNUNET_ntohll(msg->amount);
650 entries = GNUNET_ntohll(msg->entries); 650 entries = ntohl(msg->entries);
651 used = plugin->api->get_size (plugin->api->cls) + reserved; 651 used = plugin->api->get_size (plugin->api->cls) + reserved;
652 req = amount + ((unsigned long long) GNUNET_DATASTORE_ENTRY_OVERHEAD) * entries; 652 req = amount + ((unsigned long long) GNUNET_DATASTORE_ENTRY_OVERHEAD) * entries;
653 if (used + req > quota) 653 if (used + req > quota)
diff --git a/src/datastore/plugin_datastore_sqlite.c b/src/datastore/plugin_datastore_sqlite.c
index 9a807463a..af4dcc322 100644
--- a/src/datastore/plugin_datastore_sqlite.c
+++ b/src/datastore/plugin_datastore_sqlite.c
@@ -29,7 +29,7 @@
29#include "plugin_datastore.h" 29#include "plugin_datastore.h"
30#include <sqlite3.h> 30#include <sqlite3.h>
31 31
32#define DEBUG_SQLITE GNUNET_YES 32#define DEBUG_SQLITE GNUNET_NO
33 33
34/** 34/**
35 * After how many payload-changing operations 35 * After how many payload-changing operations
@@ -44,7 +44,7 @@
44 * a failure of the command 'cmd' on file 'filename' 44 * a failure of the command 'cmd' on file 'filename'
45 * with the message given by strerror(errno). 45 * with the message given by strerror(errno).
46 */ 46 */
47#define LOG_SQLITE(db, msg, level, cmd) do { GNUNET_log_from (level, "sqlite", _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(db->dbh)); if (msg != NULL) GNUNET_asprintf(msg, _("`%s' failed with error: %s\n"), cmd, sqlite3_errmsg(db->dbh)); } while(0) 47#define LOG_SQLITE(db, msg, level, cmd) do { GNUNET_log_from (level, "sqlite", _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(db->dbh)); if (msg != NULL) GNUNET_asprintf(msg, _("`%s' failed with error: %s"), cmd, sqlite3_errmsg(db->dbh)); } while(0)
48 48
49#define SELECT_IT_LOW_PRIORITY_1 \ 49#define SELECT_IT_LOW_PRIORITY_1 \
50 "SELECT size,type,prio,anonLevel,expire,hash,value,_ROWID_ FROM gn080 WHERE (prio = ? AND hash > ?) "\ 50 "SELECT size,type,prio,anonLevel,expire,hash,value,_ROWID_ FROM gn080 WHERE (prio = ? AND hash > ?) "\
@@ -768,7 +768,7 @@ sqlite_plugin_update (void *cls,
768 sqlite3_bind_int64 (plugin->updPrio, 2, expire.value); 768 sqlite3_bind_int64 (plugin->updPrio, 2, expire.value);
769 sqlite3_bind_int64 (plugin->updPrio, 3, uid); 769 sqlite3_bind_int64 (plugin->updPrio, 3, uid);
770 n = sqlite3_step (plugin->updPrio); 770 n = sqlite3_step (plugin->updPrio);
771 if (n != SQLITE_OK) 771 if (n != SQLITE_DONE)
772 LOG_SQLITE (plugin, msg, 772 LOG_SQLITE (plugin, msg,
773 GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, 773 GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
774 "sqlite3_step"); 774 "sqlite3_step");
@@ -782,7 +782,7 @@ sqlite_plugin_update (void *cls,
782 782
783 if (n == SQLITE_BUSY) 783 if (n == SQLITE_BUSY)
784 return GNUNET_NO; 784 return GNUNET_NO;
785 return n == SQLITE_OK ? GNUNET_OK : GNUNET_SYSERR; 785 return n == SQLITE_DONE ? GNUNET_OK : GNUNET_SYSERR;
786} 786}
787 787
788 788
diff --git a/src/datastore/test_datastore_api.c b/src/datastore/test_datastore_api.c
index 3d65bf813..005c11a58 100644
--- a/src/datastore/test_datastore_api.c
+++ b/src/datastore/test_datastore_api.c
@@ -19,13 +19,11 @@
19*/ 19*/
20/* 20/*
21 * @file datastore/test_datastore_api.c 21 * @file datastore/test_datastore_api.c
22 * @brief Test for the datastore implementation. 22 * @brief Test for the basic datastore API.
23 * @author Christian Grothoff 23 * @author Christian Grothoff
24 * 24 *
25 * TODO: 25 * TODO:
26 * - test multiple values under same key 26 * - test reservation failure
27 * - test "update"
28 * - test storage reservations
29 */ 27 */
30 28
31#include "platform.h" 29#include "platform.h"
@@ -91,7 +89,7 @@ get_expiration (int i)
91{ 89{
92 struct GNUNET_TIME_Absolute av; 90 struct GNUNET_TIME_Absolute av;
93 91
94 av.value = now.value - i * 1000; 92 av.value = now.value + 200000 - i * 1000;
95 return av; 93 return av;
96} 94}
97 95
@@ -102,7 +100,16 @@ enum RunPhase
102 RP_GET, 100 RP_GET,
103 RP_DEL, 101 RP_DEL,
104 RP_DO_DEL, 102 RP_DO_DEL,
105 RP_DELVALIDATE 103 RP_DELVALIDATE,
104 RP_RESERVE,
105 RP_PUT_MULTIPLE,
106 RP_PUT_MULTIPLE_NEXT,
107 RP_GET_MULTIPLE,
108 RP_GET_MULTIPLE_NEXT,
109 RP_GET_MULTIPLE_DONE,
110 RP_UPDATE,
111 RP_UPDATE_VALIDATE,
112 RP_UPDATE_DONE
106 }; 113 };
107 114
108 115
@@ -110,12 +117,14 @@ struct CpsRunContext
110{ 117{
111 GNUNET_HashCode key; 118 GNUNET_HashCode key;
112 int i; 119 int i;
120 int rid;
113 int *iptr; 121 int *iptr;
114 struct GNUNET_SCHEDULER_Handle *sched; 122 struct GNUNET_SCHEDULER_Handle *sched;
115 struct GNUNET_CONFIGURATION_Handle *cfg; 123 struct GNUNET_CONFIGURATION_Handle *cfg;
116 void *data; 124 void *data;
117 size_t size; 125 size_t size;
118 enum RunPhase phase; 126 enum RunPhase phase;
127 unsigned long long uid;
119}; 128};
120 129
121 130
@@ -144,6 +153,25 @@ check_success (void *cls,
144} 153}
145 154
146 155
156static void
157get_reserved (void *cls,
158 int success,
159 const char *msg)
160{
161 struct CpsRunContext *crc = cls;
162 if (0 >= success)
163 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
164 "%s\n", msg);
165 GNUNET_assert (0 < success);
166 crc->rid = success;
167 GNUNET_SCHEDULER_add_continuation (crc->sched,
168 GNUNET_NO,
169 &run_continuation,
170 crc,
171 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
172}
173
174
147static void 175static void
148check_value (void *cls, 176check_value (void *cls,
149 const GNUNET_HashCode * key, 177 const GNUNET_HashCode * key,
@@ -227,7 +255,7 @@ check_nothing (void *cls,
227 GNUNET_assert (key == NULL); 255 GNUNET_assert (key == NULL);
228 if (crc->i == 0) 256 if (crc->i == 0)
229 { 257 {
230 crc->phase = RP_DONE; 258 crc->phase = RP_RESERVE;
231 } 259 }
232 GNUNET_SCHEDULER_add_continuation (crc->sched, 260 GNUNET_SCHEDULER_add_continuation (crc->sched,
233 GNUNET_NO, 261 GNUNET_NO,
@@ -237,12 +265,81 @@ check_nothing (void *cls,
237} 265}
238 266
239 267
268static void
269check_multiple (void *cls,
270 const GNUNET_HashCode * key,
271 uint32_t size,
272 const void *data,
273 uint32_t type,
274 uint32_t priority,
275 uint32_t anonymity,
276 struct GNUNET_TIME_Absolute
277 expiration, uint64_t uid)
278{
279 struct CpsRunContext *crc = cls;
280
281 if (key == NULL)
282 {
283 GNUNET_assert (crc->phase == RP_GET_MULTIPLE_DONE);
284 crc->phase = RP_UPDATE;
285 GNUNET_SCHEDULER_add_continuation (crc->sched,
286 GNUNET_NO,
287 &run_continuation,
288 crc,
289 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
290 return;
291 }
292 crc->phase++;
293 if (priority == get_priority (42))
294 crc->uid = uid;
295}
296
297
298static void
299check_update (void *cls,
300 const GNUNET_HashCode * key,
301 uint32_t size,
302 const void *data,
303 uint32_t type,
304 uint32_t priority,
305 uint32_t anonymity,
306 struct GNUNET_TIME_Absolute
307 expiration, uint64_t uid)
308{
309 struct CpsRunContext *crc = cls;
310
311 if (key == NULL)
312 {
313 GNUNET_assert (crc->phase == RP_UPDATE_DONE);
314 crc->phase = RP_DONE;
315 GNUNET_SCHEDULER_add_continuation (crc->sched,
316 GNUNET_NO,
317 &run_continuation,
318 crc,
319 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
320 return;
321 }
322 if ( (anonymity == get_anonymity (42)) &&
323 (size == get_size (42)) &&
324 (priority == get_priority (42) + 100) )
325 {
326 crc->phase = RP_UPDATE_DONE;
327 }
328 else
329 GNUNET_assert (size == get_size (43));
330}
331
332
240static void 333static void
241run_continuation (void *cls, 334run_continuation (void *cls,
242 const struct GNUNET_SCHEDULER_TaskContext *tc) 335 const struct GNUNET_SCHEDULER_TaskContext *tc)
243{ 336{
244 struct CpsRunContext *crc = cls; 337 struct CpsRunContext *crc = cls;
245 ok = (int) crc->phase; 338 ok = (int) crc->phase;
339#if VERBOSE
340 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
341 "Test in phase %u\n", crc->phase);
342#endif
246 switch (crc->phase) 343 switch (crc->phase)
247 { 344 {
248 case RP_PUT: 345 case RP_PUT:
@@ -341,9 +438,79 @@ run_continuation (void *cls,
341 crc, 438 crc,
342 TIMEOUT); 439 TIMEOUT);
343 break; 440 break;
344 /* check reservations */ 441 case RP_RESERVE:
345 /* check update */ 442 crc->phase = RP_PUT_MULTIPLE;
346 /* test multiple results */ 443 GNUNET_DATASTORE_reserve (datastore,
444 128*1024,
445 2,
446 &get_reserved,
447 crc,
448 TIMEOUT);
449 break;
450 case RP_PUT_MULTIPLE:
451 crc->phase = RP_PUT_MULTIPLE_NEXT;
452 GNUNET_DATASTORE_put (datastore,
453 crc->rid,
454 &crc->key,
455 get_size (42),
456 get_data (42),
457 get_type (42),
458 get_priority (42),
459 get_anonymity (42),
460 get_expiration (42),
461 TIMEOUT,
462 &check_success,
463 crc);
464 break;
465 case RP_PUT_MULTIPLE_NEXT:
466 crc->phase = RP_GET_MULTIPLE;
467 GNUNET_DATASTORE_put (datastore,
468 crc->rid,
469 &crc->key,
470 get_size (43),
471 get_data (43),
472 get_type (42),
473 get_priority (43),
474 get_anonymity (43),
475 get_expiration (43),
476 TIMEOUT,
477 &check_success,
478 crc);
479 break;
480 case RP_GET_MULTIPLE:
481 GNUNET_DATASTORE_get (datastore,
482 &crc->key,
483 get_type (42),
484 &check_multiple,
485 crc,
486 TIMEOUT);
487 break;
488 case RP_GET_MULTIPLE_NEXT:
489 case RP_GET_MULTIPLE_DONE:
490 GNUNET_assert (0);
491 break;
492 case RP_UPDATE:
493 GNUNET_assert (crc->uid > 0);
494 crc->phase = RP_UPDATE_VALIDATE;
495 GNUNET_DATASTORE_update (datastore,
496 crc->uid,
497 100,
498 get_expiration (42),
499 &check_success,
500 crc,
501 TIMEOUT);
502 break;
503 case RP_UPDATE_VALIDATE:
504 GNUNET_DATASTORE_get (datastore,
505 &crc->key,
506 get_type (42),
507 &check_update,
508 crc,
509 TIMEOUT);
510 break;
511 case RP_UPDATE_DONE:
512 GNUNET_assert (0);
513 break;
347 case RP_DONE: 514 case RP_DONE:
348#if VERBOSE 515#if VERBOSE
349 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 516 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -368,7 +535,7 @@ run (void *cls,
368 crc->sched = sched; 535 crc->sched = sched;
369 crc->cfg = cfg; 536 crc->cfg = cfg;
370 crc->phase = RP_PUT; 537 crc->phase = RP_PUT;
371 now.value = 1000000; 538 now = GNUNET_TIME_absolute_get ();
372 datastore = GNUNET_DATASTORE_connect (cfg, sched); 539 datastore = GNUNET_DATASTORE_connect (cfg, sched);
373 GNUNET_SCHEDULER_add_continuation (crc->sched, 540 GNUNET_SCHEDULER_add_continuation (crc->sched,
374 GNUNET_NO, 541 GNUNET_NO,
diff --git a/src/datastore/test_datastore_api_management.c b/src/datastore/test_datastore_api_management.c
new file mode 100644
index 000000000..f5dfa8a07
--- /dev/null
+++ b/src/datastore/test_datastore_api_management.c
@@ -0,0 +1,377 @@
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_management.c
22 * @brief Test for the space management functions of the datastore implementation.
23 * @author Christian Grothoff
24 */
25
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_protocols.h"
29#include "gnunet_datastore_service.h"
30
31#define VERBOSE GNUNET_NO
32
33/**
34 * How long until we give up on transmitting the message?
35 */
36#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15)
37
38/**
39 * Number of iterations to run; must be large enough
40 * so that the quota will be exceeded!
41 */
42#define ITERATIONS 5000
43
44static struct GNUNET_DATASTORE_Handle *datastore;
45
46static struct GNUNET_TIME_Absolute now;
47
48static int ok;
49
50
51static size_t
52get_size (int i)
53{
54 return 8 + 8 * (i % 256);
55}
56
57
58static const void *
59get_data (int i)
60{
61 static char buf[60000];
62 memset (buf, i, 8 + 8 * (i % 256));
63 return buf;
64}
65
66
67static int
68get_type(int i)
69{
70 return 1;
71}
72
73
74static int
75get_priority (int i)
76{
77 return i+1;
78}
79
80
81static int
82get_anonymity(int i)
83{
84 return i;
85}
86
87
88static struct GNUNET_TIME_Absolute
89get_expiration (int i)
90{
91 struct GNUNET_TIME_Absolute av;
92
93 av.value = now.value + i * 1000;
94 return av;
95}
96
97enum RunPhase
98 {
99 RP_DONE = 0,
100 RP_PUT,
101 RP_GET,
102 RP_GET_FAIL
103 };
104
105
106struct CpsRunContext
107{
108 GNUNET_HashCode key;
109 int i;
110 int found;
111 struct GNUNET_SCHEDULER_Handle *sched;
112 struct GNUNET_CONFIGURATION_Handle *cfg;
113 void *data;
114 size_t size;
115 enum RunPhase phase;
116};
117
118
119static void
120run_continuation (void *cls,
121 const struct GNUNET_SCHEDULER_TaskContext *tc);
122
123
124static void
125check_success (void *cls,
126 int success,
127 const char *msg)
128{
129 struct CpsRunContext *crc = cls;
130 if (GNUNET_OK != success)
131 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
132 "%s\n", msg);
133 GNUNET_assert (GNUNET_OK == success);
134 GNUNET_free_non_null (crc->data);
135 crc->data = NULL;
136 GNUNET_SCHEDULER_add_continuation (crc->sched,
137 GNUNET_NO,
138 &run_continuation,
139 crc,
140 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
141}
142
143
144static void
145check_value (void *cls,
146 const GNUNET_HashCode * key,
147 uint32_t size,
148 const void *data,
149 uint32_t type,
150 uint32_t priority,
151 uint32_t anonymity,
152 struct GNUNET_TIME_Absolute
153 expiration, uint64_t uid)
154{
155 struct CpsRunContext *crc = cls;
156 int i;
157
158 if (key == NULL)
159 {
160 crc->i--;
161 if (crc->found == GNUNET_YES)
162 {
163 crc->phase = RP_GET;
164 crc->found = GNUNET_NO;
165 }
166 else
167 {
168 fprintf (stderr,
169 "First not found was %u\n", crc->i);
170 crc->phase = RP_GET_FAIL;
171 }
172 if (0 == crc->i)
173 crc->phase = RP_DONE;
174 GNUNET_SCHEDULER_add_continuation (crc->sched,
175 GNUNET_NO,
176 &run_continuation,
177 crc,
178 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
179 return;
180 }
181 i = crc->i;
182 crc->found = GNUNET_YES;
183 GNUNET_assert (size == get_size (i));
184 GNUNET_assert (0 == memcmp (data, get_data(i), size));
185 GNUNET_assert (type == get_type (i));
186 GNUNET_assert (priority == get_priority (i));
187 GNUNET_assert (anonymity == get_anonymity(i));
188 GNUNET_assert (expiration.value == get_expiration(i).value);
189}
190
191
192static void
193check_nothing (void *cls,
194 const GNUNET_HashCode * key,
195 uint32_t size,
196 const void *data,
197 uint32_t type,
198 uint32_t priority,
199 uint32_t anonymity,
200 struct GNUNET_TIME_Absolute
201 expiration, uint64_t uid)
202{
203 struct CpsRunContext *crc = cls;
204 GNUNET_assert (key == NULL);
205 if (crc->i == 0)
206 {
207 crc->phase = RP_DONE;
208 }
209 GNUNET_SCHEDULER_add_continuation (crc->sched,
210 GNUNET_NO,
211 &run_continuation,
212 crc,
213 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
214}
215
216
217static void
218run_continuation (void *cls,
219 const struct GNUNET_SCHEDULER_TaskContext *tc)
220{
221 struct CpsRunContext *crc = cls;
222 ok = (int) crc->phase;
223 switch (crc->phase)
224 {
225 case RP_PUT:
226#if VERBOSE
227 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
228 "Executing `%s' number %u\n",
229 "PUT",
230 crc->i);
231#endif
232 GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key);
233 GNUNET_DATASTORE_put (datastore,
234 0,
235 &crc->key,
236 get_size (crc->i),
237 get_data (crc->i),
238 get_type (crc->i),
239 get_priority (crc->i),
240 get_anonymity (crc->i),
241 get_expiration (crc->i),
242 TIMEOUT,
243 &check_success,
244 crc);
245 crc->i++;
246 if (crc->i == ITERATIONS)
247 {
248 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
249 "Sleeping to give datastore time to clean up\n");
250 sleep (5);
251 crc->phase = RP_GET;
252 crc->i--;
253 }
254 break;
255 case RP_GET:
256#if VERBOSE
257 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
258 "Executing `%s' number %u\n",
259 "GET",
260 crc->i);
261#endif
262 GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key);
263 GNUNET_DATASTORE_get (datastore,
264 &crc->key,
265 get_type (crc->i),
266 &check_value,
267 crc,
268 TIMEOUT);
269 break;
270 case RP_GET_FAIL:
271#if VERBOSE
272 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
273 "Executing `%s' number %u\n",
274 "GET",
275 crc->i);
276#endif
277 GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key);
278 GNUNET_DATASTORE_get (datastore,
279 &crc->key,
280 get_type (crc->i),
281 &check_nothing,
282 crc,
283 TIMEOUT);
284 break;
285 case RP_DONE:
286#if VERBOSE
287 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
288 "Finished, disconnecting\n");
289#endif
290 GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES);
291 GNUNET_free (crc);
292 ok = 0;
293 }
294}
295
296
297static void
298run (void *cls,
299 struct GNUNET_SCHEDULER_Handle *sched,
300 char *const *args,
301 const char *cfgfile, struct GNUNET_CONFIGURATION_Handle *cfg)
302{
303 struct CpsRunContext *crc;
304
305 crc = GNUNET_malloc(sizeof(struct CpsRunContext));
306 crc->sched = sched;
307 crc->cfg = cfg;
308 crc->phase = RP_PUT;
309 now = GNUNET_TIME_absolute_get ();
310 datastore = GNUNET_DATASTORE_connect (cfg, sched);
311 GNUNET_SCHEDULER_add_continuation (crc->sched,
312 GNUNET_NO,
313 &run_continuation,
314 crc,
315 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
316
317}
318
319
320
321static int
322check ()
323{
324 pid_t pid;
325 char *const argv[] = { "test-datastore-api-management",
326 "-c",
327 "test_datastore_api_data.conf",
328#if VERBOSE
329 "-L", "DEBUG",
330#endif
331 NULL
332 };
333 struct GNUNET_GETOPT_CommandLineOption options[] = {
334 GNUNET_GETOPT_OPTION_END
335 };
336 pid = GNUNET_OS_start_process ("gnunet-service-datastore",
337 "gnunet-service-datastore",
338#if VERBOSE
339 "-L", "DEBUG",
340#endif
341 "-c", "test_datastore_api_data.conf", NULL);
342 sleep (1);
343 GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
344 argv, "test-datastore-api", "nohelp",
345 options, &run, NULL);
346 if (0 != PLIBC_KILL (pid, SIGTERM))
347 {
348 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
349 ok = 1;
350 }
351 GNUNET_OS_process_wait(pid);
352 if (ok != 0)
353 fprintf (stderr, "Missed some testcases: %u\n", ok);
354 return ok;
355}
356
357int
358main (int argc, char *argv[])
359{
360 int ret;
361
362 GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-datastore");
363 GNUNET_log_setup ("test-datastore-api",
364#if VERBOSE
365 "DEBUG",
366#else
367 "WARNING",
368#endif
369 NULL);
370 ret = check ();
371
372 return ret;
373}
374
375
376
377/* end of test_datastore_api_management.c */