aboutsummaryrefslogtreecommitdiff
path: root/src/service/namestore/test_namestore_api_edit_records.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/service/namestore/test_namestore_api_edit_records.c')
-rw-r--r--src/service/namestore/test_namestore_api_edit_records.c399
1 files changed, 399 insertions, 0 deletions
diff --git a/src/service/namestore/test_namestore_api_edit_records.c b/src/service/namestore/test_namestore_api_edit_records.c
new file mode 100644
index 000000000..94b4f4fc1
--- /dev/null
+++ b/src/service/namestore/test_namestore_api_edit_records.c
@@ -0,0 +1,399 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2022 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 namestore/test_namestore_api_edit_records.c
22 * @brief testcase for namestore_api.c: Multiple clients work with record set.
23 */
24#include "platform.h"
25#include "gnunet_namestore_service.h"
26#include "gnunet_testing_lib.h"
27
28#define TEST_RECORD_TYPE GNUNET_DNSPARSER_TYPE_TXT
29
30#define TEST_RECORD_DATALEN 123
31
32#define TEST_RECORD_DATA 'a'
33
34#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 100)
35
36
37static struct GNUNET_NAMESTORE_Handle *nsh;
38
39static struct GNUNET_NAMESTORE_Handle *nsh2;
40
41static struct GNUNET_SCHEDULER_Task *endbadly_task;
42
43static struct GNUNET_CRYPTO_PrivateKey privkey;
44
45static struct GNUNET_CRYPTO_PublicKey pubkey;
46
47static int res;
48
49static int removed;
50
51static struct GNUNET_NAMESTORE_QueueEntry *nsqe;
52
53static int nonce = 0;
54
55static void
56cleanup ()
57{
58 if (NULL != nsh)
59 {
60 GNUNET_NAMESTORE_disconnect (nsh);
61 nsh = NULL;
62 }
63 GNUNET_SCHEDULER_shutdown ();
64}
65
66
67/**
68 * Re-establish the connection to the service.
69 *
70 * @param cls handle to use to re-connect.
71 */
72static void
73endbadly (void *cls)
74{
75 if (NULL != nsqe)
76 {
77 GNUNET_NAMESTORE_cancel (nsqe);
78 nsqe = NULL;
79 }
80 cleanup ();
81 res = 1;
82}
83
84
85static void
86end (void *cls)
87{
88 cleanup ();
89 res = 0;
90}
91
92static void
93lookup_it (void *cls,
94 const struct GNUNET_CRYPTO_PrivateKey *zone,
95 const char *label,
96 unsigned int rd_count,
97 const struct GNUNET_GNSRECORD_Data *rd)
98{
99 GNUNET_assert (0 == rd_count);
100 GNUNET_SCHEDULER_add_now (&end, NULL);
101}
102
103static void
104fail_cb (void *cls)
105{
106 if (endbadly_task != NULL)
107 GNUNET_SCHEDULER_cancel (endbadly_task);
108 endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
109 return;
110}
111
112static void
113remove_cont (void *cls,
114 enum GNUNET_ErrorCode ec)
115{
116 nsqe = NULL;
117 if (GNUNET_EC_NONE != ec)
118 {
119 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
120 _ ("Unable to roll back: `%s'\n"),
121 GNUNET_ErrorCode_get_hint (ec));
122 if (NULL != endbadly_task)
123 GNUNET_SCHEDULER_cancel (endbadly_task);
124 endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly,
125 NULL);
126 return;
127 }
128 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
129 "Rolled back, perform lookup\n");
130 removed = GNUNET_YES;
131 if (NULL != endbadly_task)
132 GNUNET_SCHEDULER_cancel (endbadly_task);
133 GNUNET_SCHEDULER_add_now (&end, NULL);
134}
135
136static void
137fail_cb_lock (void *cls);
138
139static void
140edit_cont_b (void *cls,
141 const struct GNUNET_CRYPTO_PrivateKey *zone,
142 const char *label,
143 unsigned int rd_count,
144 const struct GNUNET_GNSRECORD_Data *rd)
145{
146 const char *name = cls;
147 /**
148 * We should probably never get here right at first.
149 * We may want to change the blocking of nsh2 so that we do get this
150 * eventually instead of the error callback above when locked.
151 */
152 if (0 == nonce)
153 {
154 if (endbadly_task != NULL)
155 GNUNET_SCHEDULER_cancel (endbadly_task);
156 endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
157 return;
158
159 }
160 /* Abort transaction for B */
161 nsqe = GNUNET_NAMESTORE_transaction_rollback (nsh2, remove_cont,
162 (void *) name);
163}
164
165
166static void
167commit_cont_a (void *cls,
168 enum GNUNET_ErrorCode ec)
169{
170 const char *name = cls;
171
172 GNUNET_assert (NULL != cls);
173 nsqe = NULL;
174 if (GNUNET_EC_NONE != ec)
175 {
176 GNUNET_break (0);
177 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
178 "Namestore could not store record: `%s'\n",
179 GNUNET_ErrorCode_get_hint (ec));
180 if (endbadly_task != NULL)
181 GNUNET_SCHEDULER_cancel (endbadly_task);
182 endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
183 return;
184 }
185
186 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
187 "Name store added record for `%s': %s\n",
188 name,
189 (GNUNET_EC_NONE == ec) ? "SUCCESS" : "FAIL");
190 /**
191 * Try again for B
192 */
193 nsqe = GNUNET_NAMESTORE_records_edit (nsh2,
194 &privkey,
195 name,
196 &fail_cb_lock,
197 (void *) name,
198 &edit_cont_b,
199 (void *) name);
200
201 GNUNET_assert (NULL != nsqe);
202}
203
204static void
205fail_cb_lock (void *cls)
206{
207 const char *name = cls;
208 if (1 == nonce)
209 {
210 if (endbadly_task != NULL)
211 GNUNET_SCHEDULER_cancel (endbadly_task);
212 endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
213 return;
214 }
215 nonce = 1;
216 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
217 "Failed to aquire additional lock\n");
218 /* Now, we stop the transaction for B */
219 nsqe = GNUNET_NAMESTORE_transaction_commit (nsh, commit_cont_a,
220 (void *) name);
221}
222
223
224static void
225begin_cont_b (void *cls,
226 enum GNUNET_ErrorCode ec)
227{
228 const char *name = cls;
229
230 GNUNET_assert (GNUNET_EC_NONE == ec);
231 /** Now, we expect this to "hang" let's see how this behaves in practice. */
232 nsqe = GNUNET_NAMESTORE_records_edit (nsh2,
233 &privkey,
234 name,
235 &fail_cb_lock,
236 (void *) name,
237 &edit_cont_b,
238 (void *) name);
239
240 GNUNET_assert (NULL != nsqe);
241}
242
243
244static void
245edit_cont (void *cls,
246 const struct GNUNET_CRYPTO_PrivateKey *zone,
247 const char *label,
248 unsigned int rd_count,
249 const struct GNUNET_GNSRECORD_Data *rd)
250{
251 const char *name = cls;
252
253 GNUNET_assert (1 == rd_count);
254 /* Now, we start a transaction for B */
255 nsqe = GNUNET_NAMESTORE_transaction_begin (nsh2, begin_cont_b, (void *) name);
256}
257
258
259static void
260begin_cont (void *cls,
261 enum GNUNET_ErrorCode ec)
262{
263 const char *name = cls;
264
265 GNUNET_assert (GNUNET_EC_NONE == ec);
266 nsqe = GNUNET_NAMESTORE_records_edit (nsh,
267 &privkey,
268 name,
269 &fail_cb,
270 (void *) name,
271 &edit_cont,
272 (void *) name);
273
274 GNUNET_assert (NULL != nsqe);
275}
276
277static void
278preload_cont (void *cls,
279 enum GNUNET_ErrorCode ec)
280{
281 const char *name = cls;
282
283 GNUNET_assert (NULL != cls);
284 nsqe = NULL;
285 if (GNUNET_EC_NONE != ec)
286 {
287 GNUNET_break (0);
288 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
289 "Namestore could not store record: `%s'\n",
290 GNUNET_ErrorCode_get_hint (ec));
291 if (endbadly_task != NULL)
292 GNUNET_SCHEDULER_cancel (endbadly_task);
293 endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
294 return;
295 }
296
297 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
298 "Name store added record for `%s': %s\n",
299 name,
300 (GNUNET_EC_NONE == ec) ? "SUCCESS" : "FAIL");
301 /* We start transaction for A */
302 nsqe = GNUNET_NAMESTORE_transaction_begin (nsh, begin_cont, (void *) name);
303
304}
305
306
307static void
308run (void *cls,
309 const struct GNUNET_CONFIGURATION_Handle *cfg,
310 struct GNUNET_TESTING_Peer *peer)
311{
312 struct GNUNET_GNSRECORD_Data rd;
313 const char *name = "dummy";
314
315 endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
316 &endbadly,
317 NULL);
318 nsh = GNUNET_NAMESTORE_connect (cfg);
319 nsh2 = GNUNET_NAMESTORE_connect (cfg);
320 GNUNET_break (NULL != nsh);
321 GNUNET_break (NULL != nsh2);
322
323 privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
324 GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key);
325 GNUNET_CRYPTO_key_get_public (&privkey,
326 &pubkey);
327
328 removed = GNUNET_NO;
329
330 rd.expiration_time = GNUNET_TIME_absolute_get ().abs_value_us;
331 rd.record_type = TEST_RECORD_TYPE;
332 rd.data_size = TEST_RECORD_DATALEN;
333 rd.data = GNUNET_malloc (TEST_RECORD_DATALEN);
334 rd.flags = 0;
335 memset ((char *) rd.data,
336 'a',
337 TEST_RECORD_DATALEN);
338 nsqe = GNUNET_NAMESTORE_records_store (nsh,
339 &privkey,
340 name,
341 1,
342 &rd,
343 &preload_cont,
344 (void *) name);
345 GNUNET_assert (NULL != nsqe);
346 GNUNET_free_nz ((void *) rd.data);
347
348 /*nsqe = GNUNET_NAMESTORE_transaction_commit (nsh, commit_cont);
349 nsqe = GNUNET_NAMESTORE_transaction_rollback (nsh, rollback_cont); Must also happen on disconnect
350 nsqe = GNUNET_NAMESTORE_records_edit (nsh,
351 &privkey,
352 name,
353 1,
354 &rd,
355 &edit_cont,
356 (void *) name);
357 nsqe = GNUNET_NAMESTORE_records_insert_bulk (nsh,
358 count,
359 &rd,
360 &
361 nsqe = GNUNET_NAMESTORE_records_store (nsh,
362 &privkey,
363 name,
364 1,
365 &rd,
366 &put_cont,
367 (void *) name);*/
368 GNUNET_assert (NULL != nsqe);
369}
370
371
372#include "test_common.c"
373
374
375int
376main (int argc, char *argv[])
377{
378 char *plugin_name;
379 char *cfg_name;
380
381 SETUP_CFG (plugin_name, cfg_name);
382 res = 1;
383 if (0 !=
384 GNUNET_TESTING_peer_run ("test-namestore-api-remove",
385 cfg_name,
386 &run,
387 NULL))
388 {
389 res = 1;
390 }
391 GNUNET_DISK_purge_cfg_dir (cfg_name,
392 "GNUNET_TEST_HOME");
393 GNUNET_free (plugin_name);
394 GNUNET_free (cfg_name);
395 return res;
396}
397
398
399/* end of test_namestore_api_remove.c */