aboutsummaryrefslogtreecommitdiff
path: root/src/testing
diff options
context:
space:
mode:
authorNathan S. Evans <evans@in.tum.de>2011-04-05 14:37:56 +0000
committerNathan S. Evans <evans@in.tum.de>2011-04-05 14:37:56 +0000
commit8da74da33f616eecdba93e9c94715a3e6244876f (patch)
tree0dc800404f4fc630206768eae09ff24921731a86 /src/testing
parent143df85a4543bad389083f959329a98023c78ee4 (diff)
downloadgnunet-8da74da33f616eecdba93e9c94715a3e6244876f.tar.gz
gnunet-8da74da33f616eecdba93e9c94715a3e6244876f.zip
initial peergroup convenience implementation
Diffstat (limited to 'src/testing')
-rw-r--r--src/testing/Makefile.am3
-rw-r--r--src/testing/test_testing_group_remote.c2
-rw-r--r--src/testing/testing_peergroup.c644
3 files changed, 647 insertions, 2 deletions
diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am
index 8084a9779..1d7806a2a 100644
--- a/src/testing/Makefile.am
+++ b/src/testing/Makefile.am
@@ -13,7 +13,8 @@ lib_LTLIBRARIES = libgnunettesting.la
13 13
14libgnunettesting_la_SOURCES = \ 14libgnunettesting_la_SOURCES = \
15 testing.c \ 15 testing.c \
16 testing_group.c 16 testing_group.c \
17 testing_peergroup.c
17libgnunettesting_la_LIBADD = $(XLIB) \ 18libgnunettesting_la_LIBADD = $(XLIB) \
18 $(top_builddir)/src/core/libgnunetcore.la \ 19 $(top_builddir)/src/core/libgnunetcore.la \
19 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 20 $(top_builddir)/src/statistics/libgnunetstatistics.la \
diff --git a/src/testing/test_testing_group_remote.c b/src/testing/test_testing_group_remote.c
index 6a4d0cc1e..58f3c4143 100644
--- a/src/testing/test_testing_group_remote.c
+++ b/src/testing/test_testing_group_remote.c
@@ -56,7 +56,7 @@ shutdown_callback (void *cls, const char *emsg)
56 if (emsg != NULL) 56 if (emsg != NULL)
57 { 57 {
58#if VERBOSE 58#if VERBOSE
59 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown of peers failed!\n"); 59 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown of peers failed (error %s)!\n", emsg);
60#endif 60#endif
61 if (ok == 0) 61 if (ok == 0)
62 ok = 666; 62 ok = 666;
diff --git a/src/testing/testing_peergroup.c b/src/testing/testing_peergroup.c
new file mode 100644
index 000000000..bd725fedc
--- /dev/null
+++ b/src/testing/testing_peergroup.c
@@ -0,0 +1,644 @@
1/*
2 This file is part of GNUnet
3 (C) 2008-2011 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 3, 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/**
22 * @file testing/testing_peergroup.c
23 * @brief API implementation for easy peer group creation
24 * @author Nathan Evans
25 * @author Christian Grothoff
26 *
27 */
28#include "platform.h"
29#include "gnunet_constants.h"
30#include "gnunet_arm_service.h"
31#include "gnunet_testing_lib.h"
32#include "gnunet_core_service.h"
33
34/** Globals **/
35#define DEFAULT_CONNECT_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30)
36
37#define DEFAULT_CONNECT_ATTEMPTS 2
38
39/** Struct definitions **/
40
41struct PeerGroupStartupContext
42{
43 struct GNUNET_TESTING_PeerGroup *pg;
44 const struct GNUNET_CONFIGURATION_Handle *cfg;
45 unsigned int total;
46 unsigned int peers_left;
47 unsigned int max_concurrent_connections;
48 unsigned int max_concurrent_ssh;
49 struct GNUNET_TIME_Absolute timeout;
50 GNUNET_TESTING_NotifyConnection connect_cb;
51 void *connect_cb_cls;
52 GNUNET_TESTING_NotifyCompletion peergroup_cb;
53 void *peergroup_cb_cls;
54 const struct GNUNET_TESTING_Host *hostnames;
55 enum GNUNET_TESTING_Topology topology;
56 enum GNUNET_TESTING_Topology restrict_topology;
57 const char *restrict_transports;
58 enum GNUNET_TESTING_Topology connect_topology;
59 enum GNUNET_TESTING_TopologyOption connect_topology_option;
60 double connect_topology_option_modifier;
61 int verbose;
62
63 struct ProgressMeter *hostkey_meter;
64 struct ProgressMeter *peer_start_meter;
65 struct ProgressMeter *connect_meter;
66
67 /**
68 * Task used to kill the peergroup.
69 */
70 GNUNET_SCHEDULER_TaskIdentifier die_task;
71
72 char *fail_reason;
73
74 /**
75 * Variable used to store the number of connections we should wait for.
76 */
77 unsigned int expected_connections;
78
79 /**
80 * Time when the connecting peers was started.
81 */
82 struct GNUNET_TIME_Absolute connect_start_time;
83
84 /**
85 * The total number of connections that have been created so far.
86 */
87 unsigned int total_connections;
88
89 /**
90 * The total number of connections that have failed so far.
91 */
92 unsigned int failed_connections;
93};
94
95/**
96 * Simple struct to keep track of progress, and print a
97 * percentage meter for long running tasks.
98 */
99struct ProgressMeter
100{
101 /**
102 * Total number of tasks to complete.
103 */
104 unsigned int total;
105
106 /**
107 * Print percentage done after modnum tasks.
108 */
109 unsigned int modnum;
110
111 /**
112 * Print a . each dotnum tasks.
113 */
114 unsigned int dotnum;
115
116 /**
117 * Total number completed thus far.
118 */
119 unsigned int completed;
120
121 /**
122 * Whether or not to print.
123 */
124 int print;
125
126 /**
127 * Startup string for progress meter.
128 */
129 char *startup_string;
130};
131
132
133/** Utility functions **/
134
135/**
136 * Create a meter to keep track of the progress of some task.
137 *
138 * @param total the total number of items to complete
139 * @param start_string a string to prefix the meter with (if printing)
140 * @param print GNUNET_YES to print the meter, GNUNET_NO to count
141 * internally only
142 *
143 * @return the progress meter
144 */
145static struct ProgressMeter *
146create_meter(unsigned int total, char * start_string, int print)
147{
148 struct ProgressMeter *ret;
149 ret = GNUNET_malloc(sizeof(struct ProgressMeter));
150 ret->print = print;
151 ret->total = total;
152 ret->modnum = total / 4;
153 ret->dotnum = (total / 50) + 1;
154 if (start_string != NULL)
155 ret->startup_string = GNUNET_strdup(start_string);
156 else
157 ret->startup_string = GNUNET_strdup("");
158
159 return ret;
160}
161
162/**
163 * Update progress meter (increment by one).
164 *
165 * @param meter the meter to update and print info for
166 *
167 * @return GNUNET_YES if called the total requested,
168 * GNUNET_NO if more items expected
169 */
170static int
171update_meter(struct ProgressMeter *meter)
172{
173 if (meter->print == GNUNET_YES)
174 {
175 if (meter->completed % meter->modnum == 0)
176 {
177 if (meter->completed == 0)
178 {
179 fprintf (stdout, "%sProgress: [0%%", meter->startup_string);
180 }
181 else
182 fprintf (stdout, "%d%%", (int) (((float) meter->completed
183 / meter->total) * 100));
184 }
185 else if (meter->completed % meter->dotnum == 0)
186 fprintf (stdout, ".");
187
188 if (meter->completed + 1 == meter->total)
189 fprintf (stdout, "%d%%]\n", 100);
190 fflush (stdout);
191 }
192 meter->completed++;
193
194 if (meter->completed == meter->total)
195 return GNUNET_YES;
196 return GNUNET_NO;
197}
198
199/**
200 * Reset progress meter.
201 *
202 * @param meter the meter to reset
203 *
204 * @return GNUNET_YES if meter reset,
205 * GNUNET_SYSERR on error
206 */
207static int
208reset_meter(struct ProgressMeter *meter)
209{
210 if (meter == NULL)
211 return GNUNET_SYSERR;
212
213 meter->completed = 0;
214 return GNUNET_YES;
215}
216
217/**
218 * Release resources for meter
219 *
220 * @param meter the meter to free
221 */
222static void
223free_meter(struct ProgressMeter *meter)
224{
225 GNUNET_free_non_null (meter->startup_string);
226 GNUNET_free (meter);
227}
228
229
230/** Functions for creating, starting and connecting the peergroup **/
231
232/**
233 * Check whether peers successfully shut down.
234 */
235static void
236internal_shutdown_callback(void *cls, const char *emsg)
237{
238 struct PeerGroupStartupContext *pg_start_ctx = cls;
239 if (emsg != NULL)
240 pg_start_ctx->peergroup_cb(pg_start_ctx->peergroup_cb_cls, emsg);
241 else
242 pg_start_ctx->peergroup_cb(pg_start_ctx->peergroup_cb_cls, pg_start_ctx->fail_reason);
243}
244
245/**
246 * Check if the get_handle is being used, if so stop the request. Either
247 * way, schedule the end_badly_cont function which actually shuts down the
248 * test.
249 */
250static void
251end_badly(void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
252{
253 struct PeerGroupStartupContext *pg_start_ctx = cls;
254 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failing peer group startup with error: `%s'!\n",
255 pg_start_ctx->fail_reason);
256
257 GNUNET_TESTING_daemons_stop (pg_start_ctx->pg, GNUNET_TIME_absolute_get_remaining(pg_start_ctx->timeout), &internal_shutdown_callback, pg_start_ctx);
258
259 if (pg_start_ctx->hostkey_meter != NULL)
260 free_meter (pg_start_ctx->hostkey_meter);
261 if (pg_start_ctx->peer_start_meter != NULL)
262 free_meter (pg_start_ctx->peer_start_meter);
263 if (pg_start_ctx->connect_meter != NULL)
264 free_meter (pg_start_ctx->connect_meter);
265}
266
267/**
268 * This function is called whenever a connection attempt is finished between two of
269 * the started peers (started with GNUNET_TESTING_daemons_start). The total
270 * number of times this function is called should equal the number returned
271 * from the GNUNET_TESTING_connect_topology call.
272 *
273 * The emsg variable is NULL on success (peers connected), and non-NULL on
274 * failure (peers failed to connect).
275 */
276static void
277internal_topology_callback(
278 void *cls,
279 const struct GNUNET_PeerIdentity *first,
280 const struct GNUNET_PeerIdentity *second,
281 uint32_t distance,
282 const struct GNUNET_CONFIGURATION_Handle *first_cfg,
283 const struct GNUNET_CONFIGURATION_Handle *second_cfg,
284 struct GNUNET_TESTING_Daemon *first_daemon,
285 struct GNUNET_TESTING_Daemon *second_daemon,
286 const char *emsg)
287{
288 struct PeerGroupStartupContext *pg_start_ctx = cls;
289#if TIMING
290 unsigned long long duration;
291 unsigned long long total_duration;
292 unsigned int new_connections;
293 unsigned int new_failed_connections;
294 double conns_per_sec_recent;
295 double conns_per_sec_total;
296 double failed_conns_per_sec_recent;
297 double failed_conns_per_sec_total;
298#endif
299
300#if TIMING
301 if (GNUNET_TIME_absolute_get_difference (connect_last_time,
302 GNUNET_TIME_absolute_get ()).rel_value
303 > GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
304 CONN_UPDATE_DURATION).rel_value)
305 {
306 /* Get number of new connections */
307 new_connections = total_connections - previous_connections;
308
309 /* Get number of new FAILED connections */
310 new_failed_connections = failed_connections - previous_failed_connections;
311
312 /* Get duration in seconds */
313 duration
314 = GNUNET_TIME_absolute_get_difference (connect_last_time,
315 GNUNET_TIME_absolute_get ()).rel_value
316 / 1000;
317 total_duration
318 = GNUNET_TIME_absolute_get_difference (connect_start_time,
319 GNUNET_TIME_absolute_get ()).rel_value
320 / 1000;
321
322 failed_conns_per_sec_recent = (double) new_failed_connections / duration;
323 failed_conns_per_sec_total = (double) failed_connections / total_duration;
324 conns_per_sec_recent = (double) new_connections / duration;
325 conns_per_sec_total = (double) total_connections / total_duration;
326 GNUNET_log (
327 GNUNET_ERROR_TYPE_WARNING,
328 "Recent: %.2f/s, Total: %.2f/s, Recent failed: %.2f/s, total failed %.2f/s\n",
329 conns_per_sec_recent, CONN_UPDATE_DURATION,
330 conns_per_sec_total, failed_conns_per_sec_recent,
331 failed_conns_per_sec_total);
332 connect_last_time = GNUNET_TIME_absolute_get ();
333 previous_connections = total_connections;
334 previous_failed_connections = failed_connections;
335 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
336 "have %u total_connections, %u failed\n", total_connections,
337 failed_connections);
338 }
339#endif
340
341
342 if (emsg == NULL)
343 {
344 pg_start_ctx->total_connections++;
345#if VERBOSE > 1
346 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "connected peer %s to peer %s, distance %u\n",
347 first_daemon->shortname,
348 second_daemon->shortname,
349 distance);
350#endif
351 }
352 else
353 {
354 pg_start_ctx->failed_connections++;
355#if VERBOSE
356 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to connect peer %s to peer %s with error :\n%s\n",
357 first_daemon->shortname,
358 second_daemon->shortname, emsg);
359
360 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to connect peer %s to peer %s with error :\n%s\n",
361 first_daemon->shortname,
362 second_daemon->shortname, emsg);
363#endif
364 }
365
366 GNUNET_assert(pg_start_ctx->connect_meter != NULL);
367 if (pg_start_ctx->connect_cb != NULL)
368 pg_start_ctx->connect_cb(pg_start_ctx->connect_cb_cls, first,
369 second,
370 distance,
371 first_cfg,
372 second_cfg,
373 first_daemon,
374 second_daemon,
375 emsg);
376 if (GNUNET_YES == update_meter (pg_start_ctx->connect_meter))
377 {
378#if VERBOSE
379 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
380 "Created %d total connections, which is our target number! Starting next phase of testing.\n",
381 total_connections);
382#endif
383
384#if TIMING
385 total_duration
386 = GNUNET_TIME_absolute_get_difference (connect_start_time,
387 GNUNET_TIME_absolute_get ()).rel_value
388 / 1000;
389 failed_conns_per_sec_total = (double) failed_connections / total_duration;
390 conns_per_sec_total = (double) total_connections / total_duration;
391 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
392 "Overall connection info --- Total: %u, Total Failed %u/s\n",
393 total_connections, failed_connections);
394 GNUNET_log (
395 GNUNET_ERROR_TYPE_WARNING,
396 "Overall connection info --- Total: %.2f/s, Total Failed %.2f/s\n",
397 conns_per_sec_total, failed_conns_per_sec_total);
398#endif
399
400 GNUNET_assert(pg_start_ctx->die_task != GNUNET_SCHEDULER_NO_TASK);
401 GNUNET_SCHEDULER_cancel (pg_start_ctx->die_task);
402
403 /* Call final callback, signifying that the peer group has been started and connected */
404 }
405}
406
407static void
408internal_peers_started_callback(void *cls, const struct GNUNET_PeerIdentity *id,
409 const struct GNUNET_CONFIGURATION_Handle *cfg,
410 struct GNUNET_TESTING_Daemon *d, const char *emsg)
411{
412 struct PeerGroupStartupContext *pg_start_ctx = cls;
413 if (emsg != NULL)
414 {
415 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
416 "Failed to start daemon with error: `%s'\n", emsg);
417 return;
418 }
419 GNUNET_assert (id != NULL);
420
421#if VERBOSE > 1
422 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Started daemon %llu out of %llu\n",
423 (num_peers - peers_left) + 1, num_peers);
424#endif
425
426 pg_start_ctx->peers_left--;
427
428 if (GNUNET_YES == update_meter (pg_start_ctx->peer_start_meter))
429 {
430#if VERBOSE
431 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
432 "All %d daemons started, now connecting peers!\n",
433 num_peers);
434#endif
435 GNUNET_assert(pg_start_ctx->die_task != GNUNET_SCHEDULER_NO_TASK);
436 GNUNET_SCHEDULER_cancel (pg_start_ctx->die_task);
437
438 pg_start_ctx->expected_connections = UINT_MAX;
439 if ((pg_start_ctx->pg != NULL) && (pg_start_ctx->peers_left == 0))
440 {
441 pg_start_ctx->connect_start_time = GNUNET_TIME_absolute_get ();
442 pg_start_ctx->expected_connections
443 = GNUNET_TESTING_connect_topology (
444 pg_start_ctx->pg,
445 pg_start_ctx->connect_topology,
446 pg_start_ctx->connect_topology_option,
447 pg_start_ctx->connect_topology_option_modifier,
448 DEFAULT_CONNECT_TIMEOUT,
449 DEFAULT_CONNECT_ATTEMPTS,
450 NULL, NULL);
451
452 pg_start_ctx->connect_meter
453 = create_meter (pg_start_ctx->expected_connections,
454 "Peer connection ", pg_start_ctx->verbose);
455 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
456 "Have %d expected connections\n",
457 pg_start_ctx->expected_connections);
458 }
459
460 if (pg_start_ctx->expected_connections == 0)
461 {
462 GNUNET_free_non_null(pg_start_ctx->fail_reason);
463 pg_start_ctx->fail_reason = GNUNET_strdup("from connect topology (bad return)");
464 pg_start_ctx->die_task
465 = GNUNET_SCHEDULER_add_now (&end_badly,
466 pg_start_ctx);
467 }
468
469 GNUNET_free_non_null(pg_start_ctx->fail_reason);
470 pg_start_ctx->fail_reason = GNUNET_strdup("from connect topology (timeout)");
471 pg_start_ctx->die_task
472 = GNUNET_SCHEDULER_add_delayed (
473 GNUNET_TIME_absolute_get_remaining (pg_start_ctx->timeout),
474 &end_badly,
475 pg_start_ctx);
476 }
477}
478
479/**
480 * Callback indicating that the hostkey was created for a peer.
481 *
482 * @param cls NULL
483 * @param id the peer identity
484 * @param d the daemon handle (pretty useless at this point, remove?)
485 * @param emsg non-null on failure
486 */
487static void
488internal_hostkey_callback(void *cls, const struct GNUNET_PeerIdentity *id,
489 struct GNUNET_TESTING_Daemon *d, const char *emsg)
490{
491 struct PeerGroupStartupContext *pg_start_ctx = cls;
492 unsigned int create_expected_connections;
493
494 if (emsg != NULL)
495 {
496 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
497 "Hostkey callback received error: %s\n", emsg);
498 }
499
500#if VERBOSE > 1
501 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
502 "Hostkey (%d/%d) created for peer `%s'\n",
503 num_peers - peers_left, num_peers, GNUNET_i2s(id));
504#endif
505
506 pg_start_ctx->peers_left--;
507 if (GNUNET_YES == update_meter (pg_start_ctx->hostkey_meter))
508 {
509 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
510 "All %d hostkeys created, now creating topology!\n",
511 pg_start_ctx->total);
512 GNUNET_SCHEDULER_cancel (pg_start_ctx->die_task);
513 /* Set up task in case topology creation doesn't finish
514 * within a reasonable amount of time */
515 pg_start_ctx->die_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining(pg_start_ctx->timeout),
516 &end_badly,
517 "from create_topology");
518 pg_start_ctx->peers_left = pg_start_ctx->total; /* Reset counter */
519 create_expected_connections = GNUNET_TESTING_create_topology (pg_start_ctx->pg, pg_start_ctx->topology, pg_start_ctx->restrict_topology,
520 pg_start_ctx->restrict_transports);
521 if (create_expected_connections > 0)
522 {
523 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
524 "Topology set up, have %u expected connections, now starting peers!\n", create_expected_connections);
525 GNUNET_TESTING_daemons_continue_startup (pg_start_ctx->pg);
526 }
527 else
528 {
529 GNUNET_SCHEDULER_cancel (pg_start_ctx->die_task);
530 pg_start_ctx->die_task = GNUNET_SCHEDULER_add_now (&end_badly,
531 "from create topology (bad return)");
532 }
533
534 GNUNET_SCHEDULER_cancel (pg_start_ctx->die_task);
535 pg_start_ctx->die_task
536 = GNUNET_SCHEDULER_add_delayed (
537 GNUNET_TIME_absolute_get_remaining(pg_start_ctx->timeout),
538 &end_badly,
539 "from continue startup (timeout)");
540 }
541}
542
543
544/**
545 * Start a peer group with a given number of peers. Notify
546 * on completion of peer startup and connection based on given
547 * topological constraints. Optionally notify on each
548 * established connection.
549 *
550 * @param cfg configuration template to use
551 * @param total number of daemons to start
552 * @param max_concurrent_connections for testing, how many peers can
553* we connect to simultaneously
554 * @param max_concurrent_ssh when starting with ssh, how many ssh
555 * connections will we allow at once (based on remote hosts allowed!)
556 * @param timeout total time allowed for peers to start
557 * @param connect_cb function to call each time two daemons are connected
558 * @param connect_cb_cls closure for connect_callback
559 * @param peergroup_cb function to call once all peers are up and connected
560 * @param peergroup_cb_cls closure for peergroup_cb
561 * @param hostnames linked list of host structs to use to start peers on
562 * (NULL to run on localhost only)
563 * @param topology allowed overlay topology
564 * @param restrict_topology blacklist connections to this topology
565 * @param restrict_transports specific transports to blacklist
566 * @param connect_topology topology to connect peers in (defaults to allowed
567 * topology)
568 * @param connect_topology_options options for connect topology
569 * @param connect_topology_option_modifier option modifier for connect topology
570 * @param verbose GNUNET_YES to print progress bars, GNUNET_NO otherwise
571 *
572 * @return NULL on error, otherwise handle to control peer group
573 */
574struct GNUNET_TESTING_PeerGroup *
575GNUNET_TESTING_PeerGroup_start(
576 const struct GNUNET_CONFIGURATION_Handle *cfg,
577 unsigned int total,
578 unsigned int max_concurrent_connections,
579 unsigned int max_concurrent_ssh,
580 struct GNUNET_TIME_Relative timeout,
581 GNUNET_TESTING_NotifyConnection connect_cb,
582 void *connect_cb_cls,
583 GNUNET_TESTING_NotifyCompletion peergroup_cb,
584 void *peergroup_cb_cls,
585 const struct GNUNET_TESTING_Host *hostnames,
586 enum GNUNET_TESTING_Topology topology,
587 enum GNUNET_TESTING_Topology restrict_topology,
588 const char *restrict_transports,
589 enum GNUNET_TESTING_Topology connect_topology,
590 enum GNUNET_TESTING_TopologyOption connect_topology_options,
591 double connect_topology_option_modifier, int verbose)
592{
593 struct PeerGroupStartupContext *pg_start_ctx;
594
595 GNUNET_assert(total > 0);
596 GNUNET_assert(cfg != NULL);
597
598 pg_start_ctx = GNUNET_malloc(sizeof(struct PeerGroupStartupContext));
599 pg_start_ctx->cfg = cfg;
600 pg_start_ctx->total = total;
601 pg_start_ctx->peers_left = total;
602 pg_start_ctx->max_concurrent_connections = max_concurrent_connections;
603 pg_start_ctx->max_concurrent_ssh = max_concurrent_ssh;
604 pg_start_ctx->timeout = GNUNET_TIME_relative_to_absolute(timeout);
605 pg_start_ctx->connect_cb = connect_cb_cls;
606 pg_start_ctx->peergroup_cb = peergroup_cb;
607 pg_start_ctx->peergroup_cb_cls = peergroup_cb_cls;
608 pg_start_ctx->hostnames = hostnames;
609 pg_start_ctx->topology = topology;
610 pg_start_ctx->restrict_topology = restrict_topology;
611 pg_start_ctx->restrict_transports = restrict_transports;
612 pg_start_ctx->connect_topology = connect_topology;
613 pg_start_ctx->connect_topology_option = connect_topology_options;
614 pg_start_ctx->connect_topology_option_modifier = connect_topology_option_modifier;
615 pg_start_ctx->verbose = verbose;
616 pg_start_ctx->hostkey_meter = create_meter (pg_start_ctx->peers_left, "Hostkeys created ", pg_start_ctx->verbose);
617 pg_start_ctx->peer_start_meter = create_meter (pg_start_ctx->peers_left, "Peers started ", pg_start_ctx->verbose);
618 /* Make compilers happy */
619 reset_meter(pg_start_ctx->peer_start_meter);
620 pg_start_ctx->die_task
621 = GNUNET_SCHEDULER_add_delayed (
622 GNUNET_TIME_absolute_get_remaining (
623 pg_start_ctx->timeout),
624 &end_badly,
625 "didn't generate all hostkeys within allowed startup time!");
626
627 pg_start_ctx->pg
628 = GNUNET_TESTING_daemons_start (
629 pg_start_ctx->cfg,
630 pg_start_ctx->peers_left,
631 pg_start_ctx->max_concurrent_connections,
632 pg_start_ctx->max_concurrent_ssh,
633 GNUNET_TIME_absolute_get_remaining(pg_start_ctx->timeout),
634 &internal_hostkey_callback, pg_start_ctx,
635 &internal_peers_started_callback,
636 pg_start_ctx,
637 &internal_topology_callback,
638 pg_start_ctx, pg_start_ctx->hostnames);
639
640 return pg_start_ctx->pg;
641}
642
643
644/* end of testing_peergroup.c */