aboutsummaryrefslogtreecommitdiff
path: root/src/dht/test_dht_topo.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-06-27 12:20:31 +0000
committerChristian Grothoff <christian@grothoff.org>2016-06-27 12:20:31 +0000
commit6549574748c9583f86fc35dbb47d7709cafe671d (patch)
treef2b714ca6969633fa1f50a76614a5655dead19bf /src/dht/test_dht_topo.c
parentd3834ca8024608b1dc7df467405d8a6ed31e8c05 (diff)
downloadgnunet-6549574748c9583f86fc35dbb47d7709cafe671d.tar.gz
gnunet-6549574748c9583f86fc35dbb47d7709cafe671d.zip
-misc fixes to DHT tests
Diffstat (limited to 'src/dht/test_dht_topo.c')
-rw-r--r--src/dht/test_dht_topo.c231
1 files changed, 159 insertions, 72 deletions
diff --git a/src/dht/test_dht_topo.c b/src/dht/test_dht_topo.c
index 205f6b99a..8be3064f7 100644
--- a/src/dht/test_dht_topo.c
+++ b/src/dht/test_dht_topo.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2012 GNUnet e.V. 3 Copyright (C) 2012, 2016 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 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 6 it under the terms of the GNU General Public License as published
@@ -71,12 +71,17 @@ static int ok = 1;
71/** 71/**
72 * Task to do DHT_puts 72 * Task to do DHT_puts
73 */ 73 */
74static struct GNUNET_SCHEDULER_Task * put_task; 74static struct GNUNET_SCHEDULER_Task *put_task;
75
76/**
77 * Task to do DHT_gets
78 */
79static struct GNUNET_SCHEDULER_Task *get_task;
75 80
76/** 81/**
77 * Task to time out / regular shutdown. 82 * Task to time out / regular shutdown.
78 */ 83 */
79static struct GNUNET_SCHEDULER_Task * timeout_task; 84static struct GNUNET_SCHEDULER_Task *timeout_task;
80 85
81/** 86/**
82 * Head of list of active GET operations. 87 * Head of list of active GET operations.
@@ -147,6 +152,39 @@ static struct
147}; 152};
148 153
149 154
155static struct GNUNET_DHT_TEST_Context *
156stop_ops ()
157{
158 struct GetOperation *get_op;
159 struct GNUNET_DHT_TEST_Context *ctx = NULL;
160
161 if (NULL != timeout_task)
162 {
163 ctx = GNUNET_SCHEDULER_cancel (timeout_task);
164 timeout_task = NULL;
165 }
166 if (NULL != put_task)
167 {
168 GNUNET_SCHEDULER_cancel (put_task);
169 put_task = NULL;
170 }
171 if (NULL != get_task)
172 {
173 GNUNET_SCHEDULER_cancel (get_task);
174 get_task = NULL;
175 }
176 while (NULL != (get_op = get_tail))
177 {
178 GNUNET_DHT_get_stop (get_op->get);
179 GNUNET_CONTAINER_DLL_remove (get_head,
180 get_tail,
181 get_op);
182 GNUNET_free (get_op);
183 }
184 return ctx;
185}
186
187
150/** 188/**
151 * Function called once we're done processing stats. 189 * Function called once we're done processing stats.
152 * 190 *
@@ -163,10 +201,11 @@ stats_finished (void *cls,
163 unsigned int i; 201 unsigned int i;
164 202
165 if (NULL != op) 203 if (NULL != op)
166 GNUNET_TESTBED_operation_done (op); // needed? 204 GNUNET_TESTBED_operation_done (op);
167 if (NULL != emsg) 205 if (NULL != emsg)
168 { 206 {
169 fprintf (stderr, _("Gathering statistics failed: %s\n"), 207 fprintf (stderr,
208 _("Gathering statistics failed: %s\n"),
170 emsg); 209 emsg);
171 GNUNET_SCHEDULER_cancel (put_task); 210 GNUNET_SCHEDULER_cancel (put_task);
172 GNUNET_DHT_TEST_cleanup (ctx); 211 GNUNET_DHT_TEST_cleanup (ctx);
@@ -178,8 +217,8 @@ stats_finished (void *cls,
178 stats[i].subsystem, 217 stats[i].subsystem,
179 stats[i].name, 218 stats[i].name,
180 stats[i].total); 219 stats[i].total);
181 GNUNET_SCHEDULER_cancel (put_task);
182 GNUNET_DHT_TEST_cleanup (ctx); 220 GNUNET_DHT_TEST_cleanup (ctx);
221 GNUNET_SCHEDULER_shutdown ();
183} 222}
184 223
185 224
@@ -191,8 +230,8 @@ stats_finished (void *cls,
191 * @param subsystem name of subsystem that created the statistic 230 * @param subsystem name of subsystem that created the statistic
192 * @param name the name of the datum 231 * @param name the name of the datum
193 * @param value the current value 232 * @param value the current value
194 * @param is_persistent GNUNET_YES if the value is persistent, GNUNET_NO if not 233 * @param is_persistent #GNUNET_YES if the value is persistent, #GNUNET_NO if not
195 * @return GNUNET_OK to continue, GNUNET_SYSERR to abort iteration 234 * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
196 */ 235 */
197static int 236static int
198handle_stats (void *cls, 237handle_stats (void *cls,
@@ -215,32 +254,31 @@ handle_stats (void *cls,
215 254
216 255
217/** 256/**
218 * Task run on success or timeout to clean up. 257 * Task run on shutdown to clean up. Terminates active get operations
219 * Terminates active get operations and shuts down 258 * and shuts down the testbed.
220 * the testbed.
221 * 259 *
222 * @param cls the 'struct GNUNET_DHT_TestContext' 260 * @param cls the 'struct GNUNET_DHT_TestContext'
223 */ 261 */
224static void 262static void
225shutdown_task (void *cls) 263shutdown_task (void *cls)
226{ 264{
227 struct GNUNET_DHT_TEST_Context *ctx = cls; 265 (void) stop_ops ();
228 struct GetOperation *get_op; 266}
229 267
230 while (NULL != (get_op = get_tail)) 268
231 { 269/**
232 GNUNET_DHT_get_stop (get_op->get); 270 * Task run on timeout to clean up. Terminates active get operations
233 GNUNET_CONTAINER_DLL_remove (get_head, 271 * and shuts down the testbed.
234 get_tail, 272 *
235 get_op); 273 * @param cls the `struct GNUNET_DHT_TestContext`
236 GNUNET_free (get_op); 274 */
237 } 275static void
238 (void) GNUNET_TESTBED_get_statistics (NUM_PEERS, 276timeout_cb (void *cls)
239 my_peers, 277{
240 NULL, NULL, 278 timeout_task = NULL;
241 &handle_stats, 279 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
242 &stats_finished, 280 "Timeout\n");
243 ctx); 281 GNUNET_SCHEDULER_shutdown ();
244} 282}
245 283
246 284
@@ -252,33 +290,40 @@ shutdown_task (void *cls)
252 * @param exp when will this value expire 290 * @param exp when will this value expire
253 * @param key key of the result 291 * @param key key of the result
254 * @param get_path peers on reply path (or NULL if not recorded) 292 * @param get_path peers on reply path (or NULL if not recorded)
255 * @param get_path_length number of entries in get_path 293 * @param get_path_length number of entries in @a get_path
256 * @param put_path peers on the PUT path (or NULL if not recorded) 294 * @param put_path peers on the PUT path (or NULL if not recorded)
257 * @param put_path_length number of entries in get_path 295 * @param put_path_length number of entries in @a put_path
258 * @param type type of the result 296 * @param type type of the result
259 * @param size number of bytes in data 297 * @param size number of bytes in @a data
260 * @param data pointer to the result data 298 * @param data pointer to the result data
261 */ 299 */
262static void 300static void
263dht_get_handler (void *cls, struct GNUNET_TIME_Absolute exp, 301dht_get_handler (void *cls,
264 const struct GNUNET_HashCode * key, 302 struct GNUNET_TIME_Absolute exp,
303 const struct GNUNET_HashCode *key,
265 const struct GNUNET_PeerIdentity *get_path, 304 const struct GNUNET_PeerIdentity *get_path,
266 unsigned int get_path_length, 305 unsigned int get_path_length,
267 const struct GNUNET_PeerIdentity *put_path, 306 const struct GNUNET_PeerIdentity *put_path,
268 unsigned int put_path_length, enum GNUNET_BLOCK_Type type, 307 unsigned int put_path_length,
269 size_t size, const void *data) 308 enum GNUNET_BLOCK_Type type,
309 size_t size,
310 const void *data)
270{ 311{
271 struct GetOperation *get_op = cls; 312 struct GetOperation *get_op = cls;
272 struct GNUNET_HashCode want; 313 struct GNUNET_HashCode want;
273 struct GNUNET_DHT_TestContext *ctx; 314 struct GNUNET_DHT_TEST_Context *ctx;
274 315
275 if (sizeof (struct GNUNET_HashCode) != size) 316 if (sizeof (struct GNUNET_HashCode) != size)
276 { 317 {
277 GNUNET_break (0); 318 GNUNET_break (0);
278 return; 319 return;
279 } 320 }
280 GNUNET_CRYPTO_hash (key, sizeof (*key), &want); 321 GNUNET_CRYPTO_hash (key,
281 if (0 != memcmp (&want, data, sizeof (want))) 322 sizeof (*key),
323 &want);
324 if (0 != memcmp (&want,
325 data,
326 sizeof (want)))
282 { 327 {
283 GNUNET_break (0); 328 GNUNET_break (0);
284 return; 329 return;
@@ -289,14 +334,19 @@ dht_get_handler (void *cls, struct GNUNET_TIME_Absolute exp,
289 { 334 {
290 int i; 335 int i;
291 336
292 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PATH: (get %u, put %u)\n", 337 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
293 get_path_length, put_path_length); 338 "PATH: (get %u, put %u)\n",
294 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " LOCAL\n"); 339 get_path_length,
340 put_path_length);
341 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
342 " LOCAL\n");
295 for (i = get_path_length - 1; i >= 0; i--) 343 for (i = get_path_length - 1; i >= 0; i--)
296 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %s\n", 344 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
345 " %s\n",
297 GNUNET_i2s (&get_path[i])); 346 GNUNET_i2s (&get_path[i]));
298 for (i = put_path_length - 1; i >= 0; i--) 347 for (i = put_path_length - 1; i >= 0; i--)
299 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %s\n", 348 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
349 " %s\n",
300 GNUNET_i2s (&put_path[i])); 350 GNUNET_i2s (&put_path[i]));
301 } 351 }
302#endif 352#endif
@@ -307,10 +357,18 @@ dht_get_handler (void *cls, struct GNUNET_TIME_Absolute exp,
307 GNUNET_free (get_op); 357 GNUNET_free (get_op);
308 if (NULL != get_head) 358 if (NULL != get_head)
309 return; 359 return;
310 /* all DHT GET operations successful; terminate! */ 360 /* all DHT GET operations successful; get stats! */
361 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
362 "All DHT operations successful. Obtaining stats!\n");
311 ok = 0; 363 ok = 0;
312 ctx = GNUNET_SCHEDULER_cancel (timeout_task); 364 ctx = stop_ops ();
313 timeout_task = GNUNET_SCHEDULER_add_now (&shutdown_task, ctx); 365 GNUNET_assert (NULL != ctx);
366 (void) GNUNET_TESTBED_get_statistics (NUM_PEERS,
367 my_peers,
368 NULL, NULL,
369 &handle_stats,
370 &stats_finished,
371 ctx);
314} 372}
315 373
316 374
@@ -328,55 +386,52 @@ do_puts (void *cls)
328 struct GNUNET_HashCode value; 386 struct GNUNET_HashCode value;
329 unsigned int i; 387 unsigned int i;
330 388
389 put_task = NULL;
331 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 390 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
332 "Putting values into DHT\n"); 391 "Putting values into DHT\n");
333 for (i = 0; i < NUM_PEERS; i++) 392 for (i = 0; i < NUM_PEERS; i++)
334 { 393 {
335 GNUNET_CRYPTO_hash (&i, sizeof (i), &key); 394 GNUNET_CRYPTO_hash (&i,
336 GNUNET_CRYPTO_hash (&key, sizeof (key), &value); 395 sizeof (i),
337 GNUNET_DHT_put (hs[i], &key, 10U, 396 &key);
397 GNUNET_CRYPTO_hash (&key,
398 sizeof (key),
399 &value);
400 GNUNET_DHT_put (hs[i],
401 &key,
402 10U,
338 GNUNET_DHT_RO_RECORD_ROUTE | 403 GNUNET_DHT_RO_RECORD_ROUTE |
339 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, 404 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
340 GNUNET_BLOCK_TYPE_TEST, 405 GNUNET_BLOCK_TYPE_TEST,
341 sizeof (value), &value, 406 sizeof (value),
407 &value,
342 GNUNET_TIME_UNIT_FOREVER_ABS, 408 GNUNET_TIME_UNIT_FOREVER_ABS,
343 NULL, NULL); 409 NULL,
410 NULL);
344 } 411 }
345 put_task = GNUNET_SCHEDULER_add_delayed (PUT_FREQUENCY, 412 put_task = GNUNET_SCHEDULER_add_delayed (PUT_FREQUENCY,
346 &do_puts, hs); 413 &do_puts,
414 hs);
347} 415}
348 416
349 417
350/** 418/**
351 * Main function of the test. 419 * Start GET operations.
352 *
353 * @param cls closure (NULL)
354 * @param ctx argument to give to GNUNET_DHT_TEST_cleanup on test end
355 * @param num_peers number of peers that are running
356 * @param peers array of peers
357 * @param dhts handle to each of the DHTs of the peers
358 */ 420 */
359static void 421static void
360run (void *cls, 422start_get (void *cls)
361 struct GNUNET_DHT_TEST_Context *ctx,
362 unsigned int num_peers,
363 struct GNUNET_TESTBED_Peer **peers,
364 struct GNUNET_DHT_Handle **dhts)
365{ 423{
424 struct GNUNET_DHT_Handle **dhts = cls;
366 unsigned int i; 425 unsigned int i;
367 unsigned int j; 426 unsigned int j;
368 struct GNUNET_HashCode key; 427 struct GNUNET_HashCode key;
369 struct GetOperation *get_op; 428 struct GetOperation *get_op;
370 429
371 GNUNET_assert (NUM_PEERS == num_peers); 430 get_task = NULL;
372 my_peers = peers; 431 for (i=0;i<NUM_PEERS;i++)
373 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
374 "Peers setup, starting test\n");
375 put_task = GNUNET_SCHEDULER_add_now (&do_puts, dhts);
376 for (i=0;i<num_peers;i++)
377 { 432 {
378 GNUNET_CRYPTO_hash (&i, sizeof (i), &key); 433 GNUNET_CRYPTO_hash (&i, sizeof (i), &key);
379 for (j=0;j<num_peers;j++) 434 for (j=0;j<NUM_PEERS;j++)
380 { 435 {
381 get_op = GNUNET_new (struct GetOperation); 436 get_op = GNUNET_new (struct GetOperation);
382 GNUNET_CONTAINER_DLL_insert (get_head, 437 GNUNET_CONTAINER_DLL_insert (get_head,
@@ -389,11 +444,43 @@ run (void *cls,
389 GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, 444 GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
390 NULL, /* xquery */ 445 NULL, /* xquery */
391 0, /* xquery bits */ 446 0, /* xquery bits */
392 &dht_get_handler, get_op); 447 &dht_get_handler,
448 get_op);
393 } 449 }
394 } 450 }
451}
452
453
454/**
455 * Main function of the test.
456 *
457 * @param cls closure (NULL)
458 * @param ctx argument to give to #GNUNET_DHT_TEST_cleanup on test end
459 * @param num_peers number of @a peers that are running
460 * @param peers array of peers
461 * @param dhts handle to each of the DHTs of the peers
462 */
463static void
464run (void *cls,
465 struct GNUNET_DHT_TEST_Context *ctx,
466 unsigned int num_peers,
467 struct GNUNET_TESTBED_Peer **peers,
468 struct GNUNET_DHT_Handle **dhts)
469{
470 GNUNET_assert (NUM_PEERS == num_peers);
471 my_peers = peers;
472 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
473 "Peers setup, starting test\n");
474 put_task = GNUNET_SCHEDULER_add_now (&do_puts,
475 dhts);
476 get_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
477 &start_get,
478 dhts);
395 timeout_task = GNUNET_SCHEDULER_add_delayed (GET_TIMEOUT, 479 timeout_task = GNUNET_SCHEDULER_add_delayed (GET_TIMEOUT,
396 &shutdown_task, ctx); 480 &timeout_cb,
481 ctx);
482 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
483 ctx);
397} 484}
398 485
399 486