aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2009-06-15 03:28:28 +0000
committerChristian Grothoff <christian@grothoff.org>2009-06-15 03:28:28 +0000
commit17b95ebf7226cc5ca4ee7d90ff0de874b0dc7576 (patch)
treead7d7f6805b7fa23fb59b9706b5fa69b19bd0639 /src
parent6ba82f605023b5396e386fdd16e6c74ef27dbc9f (diff)
downloadgnunet-17b95ebf7226cc5ca4ee7d90ff0de874b0dc7576.tar.gz
gnunet-17b95ebf7226cc5ca4ee7d90ff0de874b0dc7576.zip
importing older testcases / benchmarks, not yet adapted to new API
Diffstat (limited to 'src')
-rw-r--r--src/datastore/Makefile.am34
-rw-r--r--src/datastore/perf_datastore_api.c284
-rw-r--r--src/datastore/perf_datastore_api_iterators.c208
-rw-r--r--src/datastore/test_datastore_api.c293
4 files changed, 809 insertions, 10 deletions
diff --git a/src/datastore/Makefile.am b/src/datastore/Makefile.am
index 839df983d..3fdf181d0 100644
--- a/src/datastore/Makefile.am
+++ b/src/datastore/Makefile.am
@@ -55,15 +55,29 @@ libgnunet_plugin_datastore_template_la_LDFLAGS = \
55 $(GN_PLUGIN_LDFLAGS) 55 $(GN_PLUGIN_LDFLAGS)
56 56
57 57
58#check_PROGRAMS = \ 58check_PROGRAMS = \
59# test_datastore_api 59 test_datastore_api \
60# 60 perf_datastore_api \
61#TESTS = $(check_PROGRAMS) 61 perf_datastore_api_iterators
62# 62
63#test_datastore_api_SOURCES = \ 63TESTS = $(check_PROGRAMS)
64# test_datastore_api.c 64
65#test_datastore_api_LDADD = \ 65test_datastore_api_SOURCES = \
66# $(top_builddir)/src/datastore/libgnunetdatastore.la \ 66 test_datastore_api.c
67# $(top_builddir)/src/util/libgnunetutil.la 67test_datastore_api_LDADD = \
68 $(top_builddir)/src/datastore/libgnunetdatastore.la \
69 $(top_builddir)/src/util/libgnunetutil.la
70
71perf_datastore_api_SOURCES = \
72 perf_datastore_api.c
73perf_datastore_api_LDADD = \
74 $(top_builddir)/src/datastore/libgnunetdatastore.la \
75 $(top_builddir)/src/util/libgnunetutil.la
76
77perf_datastore_api_iterators_SOURCES = \
78 perf_datastore_api_iterators.c
79perf_datastore_api_iterators_LDADD = \
80 $(top_builddir)/src/datastore/libgnunetdatastore.la \
81 $(top_builddir)/src/util/libgnunetutil.la
68 82
69 83
diff --git a/src/datastore/perf_datastore_api.c b/src/datastore/perf_datastore_api.c
new file mode 100644
index 000000000..5001ff2a6
--- /dev/null
+++ b/src/datastore/perf_datastore_api.c
@@ -0,0 +1,284 @@
1/*
2 This file is part of GNUnet.
3 (C) 2004, 2005, 2006, 2007 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 applications/sqstore_sqlite/sqlitetest2.c
22 * @brief Test for the sqstore implementations.
23 * @author Christian Grothoff
24 *
25 * This testcase inserts a bunch of (variable size) data and then deletes
26 * data until the (reported) database size drops below a given threshold.
27 * This is iterated 10 times, with the actual size of the content stored,
28 * the database size reported and the file size on disk being printed for
29 * each iteration. The code also prints a "I" for every 40 blocks
30 * inserted and a "D" for every 40 blocks deleted. The deletion
31 * strategy alternates between "lowest priority" and "earliest expiration".
32 * Priorities and expiration dates are set using a pseudo-random value
33 * within a realistic range.
34 * <p>
35 *
36 * Note that the disk overhead calculations are not very sane for
37 * MySQL: we take the entire /var/lib/mysql directory (best we can
38 * do for ISAM), which may contain other data and which never
39 * shrinks. The scanning of the entire mysql directory during
40 * each report is also likely to be the cause of a minor
41 * slowdown compared to sqlite.<p>
42 */
43
44#include "platform.h"
45#include "gnunet_util.h"
46#include "gnunet_protocols.h"
47#include "gnunet_sqstore_service.h"
48#include "core.h"
49
50#define ASSERT(x) do { if (! (x)) { printf("Error at %s:%d\n", __FILE__, __LINE__); goto FAILURE;} } while (0)
51
52/**
53 * Target datastore size (in bytes).
54 * <p>
55 * Example impact of total size on the reported number
56 * of operations (insert and delete) per second (once
57 * roughly stabilized -- this is not "sound" experimental
58 * data but just a rough idea) for a particular machine:
59 * <pre>
60 * 4: 60 at 7k ops total
61 * 8: 50 at 3k ops total
62 * 16: 48 at 8k ops total
63 * 32: 46 at 8k ops total
64 * 64: 61 at 9k ops total
65 * 128: 89 at 9k ops total
66 * 4092: 11 at 383k ops total (12 GB stored, 14.8 GB DB size on disk, 2.5 GB reported)
67 * </pre>
68 * Pure insertion performance into an empty DB initially peaks
69 * at about 400 ops. The performance seems to drop especially
70 * once the existing (fragmented) ISAM space is filled up and
71 * the DB needs to grow on disk. This could be explained with
72 * ISAM looking more carefully for defragmentation opportunities.
73 * <p>
74 * MySQL disk space overheads (for otherwise unused database when
75 * run with 128 MB target data size; actual size 651 MB, useful
76 * data stored 520 MB) are quite large in the range of 25-30%.
77 * <p>
78 * This kind of processing seems to be IO bound (system is roughly
79 * at 90% wait, 10% CPU). This is with MySQL 5.0.
80 *
81 */
82#define MAX_SIZE 1024LL * 1024 * 16
83
84/**
85 * Report progress outside of major reports? Should probably be GNUNET_YES if
86 * size is > 16 MB.
87 */
88#define REPORT_ID GNUNET_NO
89
90/**
91 * Number of put operations equivalent to 1/10th of MAX_SIZE
92 */
93#define PUT_10 MAX_SIZE / 32 / 1024 / 10
94
95/**
96 * Progress report frequency. 1/10th of a put operation block.
97 */
98#define REP_FREQ PUT_10 / 10
99
100/**
101 * Total number of iterations (each iteration doing
102 * PUT_10 put operations); we report full status every
103 * 10 iterations. Abort with CTRL-C.
104 */
105#define ITERATIONS 100
106
107/**
108 * Name of the database on disk.
109 * You may have to adjust this path and the access
110 * permission to the respective directory in order
111 * to obtain all of the performance information.
112 */
113#define DB_NAME "/tmp/gnunet-sqlite-sqstore-test/data/fs/"
114
115static unsigned long long stored_bytes;
116
117static unsigned long long stored_entries;
118
119static unsigned long long stored_ops;
120
121static GNUNET_CronTime start_time;
122
123static int
124putValue (GNUNET_SQstore_ServiceAPI * api, int i, int k)
125{
126 GNUNET_DatastoreValue *value;
127 size_t size;
128 static GNUNET_HashCode key;
129 static int ic;
130
131 /* most content is 32k */
132 size = sizeof (GNUNET_DatastoreValue) + 32 * 1024;
133 if (GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 16) == 0) /* but some of it is less! */
134 size =
135 sizeof (GNUNET_DatastoreValue) +
136 GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 32 * 1024);
137 size = size - (size & 7); /* always multiple of 8 */
138
139 /* generate random key */
140 GNUNET_hash (&key, sizeof (GNUNET_HashCode), &key);
141 value = GNUNET_malloc (size);
142 value->size = htonl (size);
143 value->type = htonl (i);
144 value->priority =
145 htonl (GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 100));
146 value->anonymity_level = htonl (i);
147 value->expiration_time =
148 GNUNET_htonll (GNUNET_get_time () +
149 GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 1000));
150 memset (&value[1], i, size - sizeof (GNUNET_DatastoreValue));
151 if (i > 255)
152 memset (&value[1], i - 255, (size - sizeof (GNUNET_DatastoreValue)) / 2);
153 ((char *) &value[1])[0] = k;
154 if (GNUNET_OK != api->put (&key, value))
155 {
156 GNUNET_free (value);
157 fprintf (stderr, "E");
158 return GNUNET_SYSERR;
159 }
160 ic++;
161#if REPORT_ID
162 if (ic % REP_FREQ == 0)
163 fprintf (stderr, "I");
164#endif
165 stored_bytes += ntohl (value->size);
166 stored_ops++;
167 stored_entries++;
168 GNUNET_free (value);
169 return GNUNET_OK;
170}
171
172static int
173iterateDelete (const GNUNET_HashCode * key,
174 const GNUNET_DatastoreValue * val, void *cls,
175 unsigned long long uid)
176{
177 GNUNET_SQstore_ServiceAPI *api = cls;
178 static int dc;
179
180 if (api->getSize () < MAX_SIZE)
181 return GNUNET_SYSERR;
182 if (GNUNET_shutdown_test () == GNUNET_YES)
183 return GNUNET_SYSERR;
184 dc++;
185#if REPORT_ID
186 if (dc % REP_FREQ == 0)
187 fprintf (stderr, "D");
188#endif
189 stored_bytes -= ntohl (val->size);
190 stored_entries--;
191 return GNUNET_NO;
192}
193
194/**
195 * Add testcode here!
196 */
197static int
198test (GNUNET_SQstore_ServiceAPI * api)
199{
200 int i;
201 int j;
202 unsigned long long size;
203 int have_file;
204 struct stat sbuf;
205
206 have_file = 0 == stat (DB_NAME, &sbuf);
207
208 for (i = 0; i < ITERATIONS; i++)
209 {
210#if REPORT_ID
211 fprintf (stderr, ".");
212#endif
213 /* insert data equivalent to 1/10th of MAX_SIZE */
214 for (j = 0; j < PUT_10; j++)
215 {
216 ASSERT (GNUNET_OK == putValue (api, j, i));
217 if (GNUNET_shutdown_test () == GNUNET_YES)
218 break;
219 }
220
221 /* trim down below MAX_SIZE again */
222 if ((i % 2) == 0)
223 api->iterateLowPriority (0, &iterateDelete, api);
224 else
225 api->iterateExpirationTime (0, &iterateDelete, api);
226
227 size = 0;
228 if (have_file)
229 GNUNET_disk_file_size (NULL, DB_NAME, &size, GNUNET_NO);
230 printf (
231#if REPORT_ID
232 "\n"
233#endif
234 "Useful %llu, API %llu, disk %llu (%.2f%%) / %lluk ops / %llu ops/s\n", stored_bytes / 1024, /* used size in k */
235 api->getSize () / 1024, /* API-reported size in k */
236 size / 1024, /* disk size in kb */
237 (100.0 * size / stored_bytes) - 100, /* overhead */
238 (stored_ops * 2 - stored_entries) / 1024, /* total operations (in k) */
239 1000 * (stored_ops * 2 - stored_entries) / (1 + GNUNET_get_time () - start_time)); /* operations per second */
240 if (GNUNET_shutdown_test () == GNUNET_YES)
241 break;
242 }
243 api->drop ();
244 return GNUNET_OK;
245
246FAILURE:
247 api->drop ();
248 return GNUNET_SYSERR;
249}
250
251int
252main (int argc, char *argv[])
253{
254 GNUNET_SQstore_ServiceAPI *api;
255 int ok;
256 struct GNUNET_GC_Configuration *cfg;
257 struct GNUNET_CronManager *cron;
258
259 cfg = GNUNET_GC_create ();
260 if (-1 == GNUNET_GC_parse_configuration (cfg, "check.conf"))
261 {
262 GNUNET_GC_free (cfg);
263 return -1;
264 }
265 cron = GNUNET_cron_create (NULL);
266 GNUNET_CORE_init (NULL, cfg, cron, NULL);
267 api = GNUNET_CORE_request_service ("sqstore");
268 if (api != NULL)
269 {
270 start_time = GNUNET_get_time ();
271 ok = test (api);
272 GNUNET_CORE_release_service (api);
273 }
274 else
275 ok = GNUNET_SYSERR;
276 GNUNET_CORE_done ();
277 GNUNET_cron_destroy (cron);
278 GNUNET_GC_free (cfg);
279 if (ok == GNUNET_SYSERR)
280 return 1;
281 return 0;
282}
283
284/* end of mysqltest2.c */
diff --git a/src/datastore/perf_datastore_api_iterators.c b/src/datastore/perf_datastore_api_iterators.c
new file mode 100644
index 000000000..115112faf
--- /dev/null
+++ b/src/datastore/perf_datastore_api_iterators.c
@@ -0,0 +1,208 @@
1/*
2 This file is part of GNUnet.
3 (C) 2004, 2005, 2006, 2007 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 applications/sqstore_sqlite/sqlitetest3.c
22 * @brief Profile sqstore iterators.
23 * @author Christian Grothoff
24 */
25
26#include "platform.h"
27#include "gnunet_util.h"
28#include "gnunet_protocols.h"
29#include "gnunet_sqstore_service.h"
30#include "core.h"
31
32/**
33 * Target datastore size (in bytes). Realistic sizes are
34 * more like 16 GB (not the default of 16 MB); however,
35 * those take too long to run them in the usual "make check"
36 * sequence. Hence the value used for shipping is tiny.
37 */
38#define MAX_SIZE 1024LL * 1024 * 128
39
40#define ITERATIONS 10
41
42/**
43 * Number of put operations equivalent to 1/10th of MAX_SIZE
44 */
45#define PUT_10 (MAX_SIZE / 32 / 1024 / ITERATIONS)
46
47static unsigned long long stored_bytes;
48
49static unsigned long long stored_entries;
50
51static unsigned long long stored_ops;
52
53static GNUNET_CronTime start_time;
54
55static int
56putValue (GNUNET_SQstore_ServiceAPI * api, int i, int k)
57{
58 GNUNET_DatastoreValue *value;
59 size_t size;
60 static GNUNET_HashCode key;
61 static int ic;
62
63 /* most content is 32k */
64 size = sizeof (GNUNET_DatastoreValue) + 32 * 1024;
65
66 if (GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 16) == 0) /* but some of it is less! */
67 size =
68 sizeof (GNUNET_DatastoreValue) +
69 GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 32 * 1024);
70 size = size - (size & 7); /* always multiple of 8 */
71
72 /* generate random key */
73 key.bits[0] = (unsigned int) GNUNET_get_time ();
74 GNUNET_hash (&key, sizeof (GNUNET_HashCode), &key);
75 value = GNUNET_malloc (size);
76 value->size = htonl (size);
77 value->type = htonl (i);
78 value->priority =
79 htonl (GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 100));
80 value->anonymity_level = htonl (i);
81 value->expiration_time =
82 GNUNET_htonll (GNUNET_get_time () + 60 * GNUNET_CRON_HOURS +
83 GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 1000));
84 memset (&value[1], i, size - sizeof (GNUNET_DatastoreValue));
85 if (i > 255)
86 memset (&value[1], i - 255, (size - sizeof (GNUNET_DatastoreValue)) / 2);
87 ((char *) &value[1])[0] = k;
88 if (GNUNET_OK != api->put (&key, value))
89 {
90 GNUNET_free (value);
91 fprintf (stderr, "E");
92 return GNUNET_SYSERR;
93 }
94 ic++;
95 stored_bytes += ntohl (value->size);
96 stored_ops++;
97 stored_entries++;
98 GNUNET_free (value);
99 return GNUNET_OK;
100}
101
102static int
103iterateDummy (const GNUNET_HashCode * key, const GNUNET_DatastoreValue * val,
104 void *cls, unsigned long long uid)
105{
106 if (GNUNET_shutdown_test () == GNUNET_YES)
107 return GNUNET_SYSERR;
108 return GNUNET_OK;
109}
110
111static int
112test (GNUNET_SQstore_ServiceAPI * api)
113{
114 int i;
115 int j;
116 int ret;
117 GNUNET_CronTime start;
118 GNUNET_CronTime end;
119
120 for (i = 0; i < ITERATIONS; i++)
121 {
122 /* insert data equivalent to 1/10th of MAX_SIZE */
123 start = GNUNET_get_time ();
124 for (j = 0; j < PUT_10; j++)
125 {
126 if (GNUNET_OK != putValue (api, j, i))
127 break;
128 if (GNUNET_shutdown_test () == GNUNET_YES)
129 break;
130 }
131 end = GNUNET_get_time ();
132 printf ("%3u insertion took %20llums\n", i, end - start);
133 if (GNUNET_shutdown_test () == GNUNET_YES)
134 break;
135 start = GNUNET_get_time ();
136 ret = api->iterateLowPriority (0, &iterateDummy, api);
137 end = GNUNET_get_time ();
138 printf ("%3u low priority iteration took %20llums (%d)\n", i,
139 end - start, ret);
140 if (GNUNET_shutdown_test () == GNUNET_YES)
141 break;
142 start = GNUNET_get_time ();
143 ret = api->iterateExpirationTime (0, &iterateDummy, api);
144 end = GNUNET_get_time ();
145 printf ("%3u expiration t iteration took %20llums (%d)\n", i,
146 end - start, ret);
147 if (GNUNET_shutdown_test () == GNUNET_YES)
148 break;
149 start = GNUNET_get_time ();
150 ret = api->iterateNonAnonymous (0, &iterateDummy, api);
151 end = GNUNET_get_time ();
152 printf ("%3u non anonymou iteration took %20llums (%d)\n", i,
153 end - start, ret);
154 if (GNUNET_shutdown_test () == GNUNET_YES)
155 break;
156 start = GNUNET_get_time ();
157 ret = api->iterateMigrationOrder (&iterateDummy, api);
158 end = GNUNET_get_time ();
159 printf ("%3u migration or iteration took %20llums (%d)\n", i,
160 end - start, ret);
161 if (GNUNET_shutdown_test () == GNUNET_YES)
162 break;
163 start = GNUNET_get_time ();
164 ret = api->iterateAllNow (&iterateDummy, api);
165 end = GNUNET_get_time ();
166 printf ("%3u all now iteration took %20llums (%d)\n", i,
167 end - start, ret);
168 if (GNUNET_shutdown_test () == GNUNET_YES)
169 break;
170 }
171 api->drop ();
172 return GNUNET_OK;
173}
174
175int
176main (int argc, char *argv[])
177{
178 GNUNET_SQstore_ServiceAPI *api;
179 int ok;
180 struct GNUNET_GC_Configuration *cfg;
181 struct GNUNET_CronManager *cron;
182
183 cfg = GNUNET_GC_create ();
184 if (-1 == GNUNET_GC_parse_configuration (cfg, "check.conf"))
185 {
186 GNUNET_GC_free (cfg);
187 return -1;
188 }
189 cron = GNUNET_cron_create (NULL);
190 GNUNET_CORE_init (NULL, cfg, cron, NULL);
191 api = GNUNET_CORE_request_service ("sqstore");
192 if (api != NULL)
193 {
194 start_time = GNUNET_get_time ();
195 ok = test (api);
196 GNUNET_CORE_release_service (api);
197 }
198 else
199 ok = GNUNET_SYSERR;
200 GNUNET_CORE_done ();
201 GNUNET_cron_destroy (cron);
202 GNUNET_GC_free (cfg);
203 if (ok == GNUNET_SYSERR)
204 return 1;
205 return 0;
206}
207
208/* end of sqlitetest3.c */
diff --git a/src/datastore/test_datastore_api.c b/src/datastore/test_datastore_api.c
new file mode 100644
index 000000000..d9f3c0459
--- /dev/null
+++ b/src/datastore/test_datastore_api.c
@@ -0,0 +1,293 @@
1/*
2 This file is part of GNUnet.
3 (C) 2004, 2005, 2006, 2007 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
26#include "platform.h"
27#include "gnunet_util.h"
28#include "gnunet_protocols.h"
29#include "gnunet_sqstore_service.h"
30#include "core.h"
31
32#define ASSERT(x) do { if (! (x)) { printf("Error at %s:%d\n", __FILE__, __LINE__); goto FAILURE;} } while (0)
33
34static GNUNET_CronTime now;
35
36static GNUNET_DatastoreValue *
37initValue (int i)
38{
39 GNUNET_DatastoreValue *value;
40
41 value = GNUNET_malloc (sizeof (GNUNET_DatastoreValue) + 8 * i);
42 value->size = htonl (sizeof (GNUNET_DatastoreValue) + 8 * i);
43 value->type = htonl (i);
44 value->priority = htonl (i + 1);
45 value->anonymity_level = htonl (i);
46 value->expiration_time = GNUNET_htonll (now - i * GNUNET_CRON_SECONDS);
47 memset (&value[1], i, 8 * i);
48 return value;
49}
50
51static int
52checkValue (const GNUNET_HashCode * key,
53 const GNUNET_DatastoreValue * val, void *closure,
54 unsigned long long uid)
55{
56 int i;
57 int ret;
58 GNUNET_DatastoreValue *value;
59
60 i = *(int *) closure;
61 value = initValue (i);
62 if ((value->size == val->size) &&
63 (0 == memcmp (val, value, ntohl (val->size))))
64 ret = GNUNET_OK;
65 else
66 {
67 /*
68 printf("Wanted: %u, %llu; got %u, %llu - %d\n",
69 ntohl(value->size), GNUNET_ntohll(value->expiration_time),
70 ntohl(val->size), GNUNET_ntohll(val->expiration_time),
71 memcmp(val, value, ntohl(val->size))); */
72 ret = GNUNET_SYSERR;
73 }
74 GNUNET_free (value);
75 return ret;
76}
77
78static int
79iterateUp (const GNUNET_HashCode * key, const GNUNET_DatastoreValue * val,
80 int *closure, unsigned long long uid)
81{
82 int ret;
83
84 ret = checkValue (key, val, closure, uid);
85 (*closure) += 2;
86 return ret;
87}
88
89static int
90iterateDown (const GNUNET_HashCode * key,
91 const GNUNET_DatastoreValue * val, int *closure,
92 unsigned long long uid)
93{
94 int ret;
95
96 (*closure) -= 2;
97 ret = checkValue (key, val, closure, uid);
98 return ret;
99}
100
101static int
102iterateDelete (const GNUNET_HashCode * key,
103 const GNUNET_DatastoreValue * val, void *closure,
104 unsigned long long uid)
105{
106 return GNUNET_NO;
107}
108
109static int
110iteratePriority (const GNUNET_HashCode * key,
111 const GNUNET_DatastoreValue * val,
112 GNUNET_SQstore_ServiceAPI * api, unsigned long long uid)
113{
114 api->update (uid, 4, 0);
115 return GNUNET_OK;
116}
117
118static int
119priorityCheck (const GNUNET_HashCode * key,
120 const GNUNET_DatastoreValue * val, int *closure,
121 unsigned long long uid)
122{
123 int id;
124
125 id = (*closure);
126 if (id + 1 == ntohl (val->priority))
127 return GNUNET_OK;
128 fprintf (stderr,
129 "Wrong priority, wanted %u got %u\n", id + 1,
130 ntohl (val->priority));
131 return GNUNET_SYSERR;
132}
133
134static int
135multipleCheck (const GNUNET_HashCode * key,
136 const GNUNET_DatastoreValue * val,
137 GNUNET_DatastoreValue ** last, unsigned long long uid)
138{
139 if (*last != NULL)
140 {
141 if (((*last)->size == val->size) &&
142 (0 == memcmp (*last, val, ntohl (val->size))))
143 return GNUNET_SYSERR; /* duplicate! */
144 GNUNET_free (*last);
145 }
146 *last = GNUNET_malloc (ntohl (val->size));
147 memcpy (*last, val, ntohl (val->size));
148 return GNUNET_OK;
149}
150
151
152/**
153 * Add testcode here!
154 */
155static int
156test (GNUNET_SQstore_ServiceAPI * api)
157{
158 GNUNET_DatastoreValue *value;
159 GNUNET_HashCode key;
160 unsigned long long oldSize;
161 int i;
162
163 now = 1000000;
164 oldSize = api->getSize ();
165 for (i = 0; i < 256; i++)
166 {
167 value = initValue (i);
168 memset (&key, 256 - i, sizeof (GNUNET_HashCode));
169 ASSERT (GNUNET_OK == api->put (&key, value));
170 GNUNET_free (value);
171 }
172 ASSERT (oldSize < api->getSize ());
173 for (i = 255; i >= 0; i--)
174 {
175 memset (&key, 256 - i, sizeof (GNUNET_HashCode));
176 ASSERT (1 == api->get (&key, NULL, i, &checkValue, (void *) &i));
177 }
178 ASSERT (256 ==
179 api->iterateLowPriority (GNUNET_ECRS_BLOCKTYPE_ANY, NULL, NULL));
180 ASSERT (256 ==
181 api->iterateExpirationTime (GNUNET_ECRS_BLOCKTYPE_ANY, NULL, NULL));
182 for (i = 255; i >= 0; i--)
183 {
184 memset (&key, 256 - i, sizeof (GNUNET_HashCode));
185 ASSERT (1 == api->get (&key, NULL, i, &checkValue, (void *) &i));
186 }
187
188 oldSize = api->getSize ();
189 for (i = 255; i >= 0; i -= 2)
190 {
191 memset (&key, 256 - i, sizeof (GNUNET_HashCode));
192 value = initValue (i);
193 if (1 != api->get (&key, NULL, 0, &iterateDelete, NULL))
194 {
195 GNUNET_free (value);
196 ASSERT (0);
197 }
198 GNUNET_free (value);
199 }
200 ASSERT (oldSize > api->getSize ());
201 i = 0;
202 ASSERT (128 == api->iterateLowPriority (GNUNET_ECRS_BLOCKTYPE_ANY,
203 (GNUNET_DatastoreValueIterator) &
204 iterateUp, &i));
205 ASSERT (256 == i);
206 ASSERT (128 == api->iterateExpirationTime (GNUNET_ECRS_BLOCKTYPE_ANY,
207 (GNUNET_DatastoreValueIterator) &
208 iterateDown, &i));
209 ASSERT (0 == i);
210 ASSERT (128 == api->iterateExpirationTime (GNUNET_ECRS_BLOCKTYPE_ANY,
211 (GNUNET_DatastoreValueIterator) &
212 iterateDelete, api));
213 i = 0;
214 ASSERT (0 ==
215 api->iterateExpirationTime (GNUNET_ECRS_BLOCKTYPE_ANY,
216 (GNUNET_DatastoreValueIterator) &
217 iterateDown, &i));
218 i = 42;
219 value = initValue (i);
220 memset (&key, 256 - i, sizeof (GNUNET_HashCode));
221 api->put (&key, value);
222 ASSERT (1 == api->iterateExpirationTime (GNUNET_ECRS_BLOCKTYPE_ANY,
223 (GNUNET_DatastoreValueIterator) &
224 priorityCheck, &i));
225 ASSERT (1 == api->iterateExpirationTime (GNUNET_ECRS_BLOCKTYPE_ANY,
226 (GNUNET_DatastoreValueIterator) &
227 priorityCheck, &i));
228 ASSERT (1 ==
229 api->iterateAllNow ((GNUNET_DatastoreValueIterator) &
230 iteratePriority, api));
231 i += 4;
232 ASSERT (1 == api->iterateExpirationTime (GNUNET_ECRS_BLOCKTYPE_ANY,
233 (GNUNET_DatastoreValueIterator) &
234 priorityCheck, &i));
235 GNUNET_free (value);
236
237 /* test multiple results */
238 value = initValue (i + 1);
239 api->put (&key, value);
240 GNUNET_free (value);
241
242 value = NULL;
243 ASSERT (2 == api->iterateExpirationTime (GNUNET_ECRS_BLOCKTYPE_ANY,
244 (GNUNET_DatastoreValueIterator) &
245 multipleCheck, &value));
246 GNUNET_free (value);
247 ASSERT (2 ==
248 api->iterateAllNow ((GNUNET_DatastoreValueIterator) & iterateDelete,
249 api));
250 ASSERT (0 ==
251 api->iterateExpirationTime (GNUNET_ECRS_BLOCKTYPE_ANY, NULL, NULL));
252 api->drop ();
253
254 return GNUNET_OK;
255
256FAILURE:
257 api->drop ();
258 return GNUNET_SYSERR;
259}
260
261int
262main (int argc, char *argv[])
263{
264 GNUNET_SQstore_ServiceAPI *api;
265 int ok;
266 struct GNUNET_GC_Configuration *cfg;
267 struct GNUNET_CronManager *cron;
268
269 cfg = GNUNET_GC_create ();
270 if (-1 == GNUNET_GC_parse_configuration (cfg, "check.conf"))
271 {
272 GNUNET_GC_free (cfg);
273 return -1;
274 }
275 cron = GNUNET_cron_create (NULL);
276 GNUNET_CORE_init (NULL, cfg, cron, NULL);
277 api = GNUNET_CORE_request_service ("sqstore");
278 if (api != NULL)
279 {
280 ok = test (api);
281 GNUNET_CORE_release_service (api);
282 }
283 else
284 ok = GNUNET_SYSERR;
285 GNUNET_CORE_done ();
286 GNUNET_cron_destroy (cron);
287 GNUNET_GC_free (cfg);
288 if (ok == GNUNET_SYSERR)
289 return 1;
290 return 0;
291}
292
293/* end of test_datastore_api.c */