diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2013-08-01 07:52:12 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2013-08-01 07:52:12 +0000 |
commit | d8cd71d95e21ee5de345e59bd62265deaad53b5d (patch) | |
tree | 644fcd116deabcd1a20e28f20d1cf5216d732672 /src/experimentation | |
parent | 7bf56139d0cd7499ab4cd7c194769f6768ad37b4 (diff) | |
download | gnunet-d8cd71d95e21ee5de345e59bd62265deaad53b5d.tar.gz gnunet-d8cd71d95e21ee5de345e59bd62265deaad53b5d.zip |
changes for experimentation
Diffstat (limited to 'src/experimentation')
-rw-r--r-- | src/experimentation/Makefile.am | 10 | ||||
-rw-r--r-- | src/experimentation/gnunet-daemon-experimentation.c | 2 | ||||
-rw-r--r-- | src/experimentation/gnunet-daemon-experimentation.h | 10 | ||||
-rw-r--r-- | src/experimentation/gnunet-daemon-experimentation_nodes.c | 129 | ||||
-rw-r--r-- | src/experimentation/gnunet-daemon-experimentation_scheduler.c | 37 | ||||
-rw-r--r-- | src/experimentation/test_experimentation_clique_run.c | 363 |
6 files changed, 541 insertions, 10 deletions
diff --git a/src/experimentation/Makefile.am b/src/experimentation/Makefile.am index 479a4e9be..effbbbd00 100644 --- a/src/experimentation/Makefile.am +++ b/src/experimentation/Makefile.am | |||
@@ -18,8 +18,7 @@ endif | |||
18 | 18 | ||
19 | 19 | ||
20 | if HAVE_EXPERIMENTAL | 20 | if HAVE_EXPERIMENTAL |
21 | TEXT_EXP_CLIQUE = test_experimentation_clique_connect | 21 | TEXT_EXP_CLIQUE = test_experimentation_clique_connect test_experimentation_clique_run |
22 | #test_experimentation_clique_run | ||
23 | endif | 22 | endif |
24 | 23 | ||
25 | check_PROGRAMS = \ | 24 | check_PROGRAMS = \ |
@@ -51,6 +50,13 @@ test_experimentation_clique_connect_LDADD = \ | |||
51 | $(top_builddir)/src/util/libgnunetutil.la \ | 50 | $(top_builddir)/src/util/libgnunetutil.la \ |
52 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 51 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
53 | $(top_builddir)/src/testbed/libgnunettestbed.la | 52 | $(top_builddir)/src/testbed/libgnunettestbed.la |
53 | |||
54 | test_experimentation_clique_run_SOURCES = \ | ||
55 | test_experimentation_clique_run.c | ||
56 | test_experimentation_clique_run_LDADD = \ | ||
57 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
58 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | ||
59 | $(top_builddir)/src/testbed/libgnunettestbed.la | ||
54 | 60 | ||
55 | #test_experimentation_clique_run_SOURCES = \ | 61 | #test_experimentation_clique_run_SOURCES = \ |
56 | # test_experimentation_clique_run.c | 62 | # test_experimentation_clique_run.c |
diff --git a/src/experimentation/gnunet-daemon-experimentation.c b/src/experimentation/gnunet-daemon-experimentation.c index 4ecc03d7d..cd8806985 100644 --- a/src/experimentation/gnunet-daemon-experimentation.c +++ b/src/experimentation/gnunet-daemon-experimentation.c | |||
@@ -96,9 +96,7 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
96 | } | 96 | } |
97 | 97 | ||
98 | GNUNET_EXPERIMENTATION_nodes_start (); | 98 | GNUNET_EXPERIMENTATION_nodes_start (); |
99 | /* | ||
100 | GNUNET_EXPERIMENTATION_scheduler_start (); | 99 | GNUNET_EXPERIMENTATION_scheduler_start (); |
101 | */ | ||
102 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, | 100 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, |
103 | NULL); | 101 | NULL); |
104 | } | 102 | } |
diff --git a/src/experimentation/gnunet-daemon-experimentation.h b/src/experimentation/gnunet-daemon-experimentation.h index 999c565ad..649017c7f 100644 --- a/src/experimentation/gnunet-daemon-experimentation.h +++ b/src/experimentation/gnunet-daemon-experimentation.h | |||
@@ -165,6 +165,9 @@ struct Node | |||
165 | * Array of fssuer ids | 165 | * Array of fssuer ids |
166 | */ | 166 | */ |
167 | struct GNUNET_PeerIdentity *issuer_id; | 167 | struct GNUNET_PeerIdentity *issuer_id; |
168 | |||
169 | struct ExperimentStartCtx *e_req_head; | ||
170 | struct ExperimentStartCtx *e_req_tail; | ||
168 | }; | 171 | }; |
169 | 172 | ||
170 | struct Experimentation_Issuer | 173 | struct Experimentation_Issuer |
@@ -205,8 +208,11 @@ struct Experimentation_Response | |||
205 | uint32_t issuer_count; | 208 | uint32_t issuer_count; |
206 | }; | 209 | }; |
207 | 210 | ||
208 | void | 211 | int |
209 | GNUNET_EXPERIMENT_nodes_request_start (struct Node *n, struct Experiment *e); | 212 | GNUNET_EXPERIMENTATION_nodes_rts (struct Node *n); |
213 | |||
214 | int | ||
215 | GNUNET_EXPERIMENTATION_nodes_request_start (struct Node *n, struct Experiment *e); | ||
210 | 216 | ||
211 | 217 | ||
212 | /** | 218 | /** |
diff --git a/src/experimentation/gnunet-daemon-experimentation_nodes.c b/src/experimentation/gnunet-daemon-experimentation_nodes.c index a77e841b8..0782e7ff1 100644 --- a/src/experimentation/gnunet-daemon-experimentation_nodes.c +++ b/src/experimentation/gnunet-daemon-experimentation_nodes.c | |||
@@ -547,6 +547,44 @@ static void handle_response (const struct GNUNET_PeerIdentity *peer, | |||
547 | } | 547 | } |
548 | 548 | ||
549 | /** | 549 | /** |
550 | * Handle a response | ||
551 | * | ||
552 | * @param peer the source | ||
553 | * @param message the message | ||
554 | */ | ||
555 | static void handle_start (const struct GNUNET_PeerIdentity *peer, | ||
556 | const struct GNUNET_MessageHeader *message) | ||
557 | { | ||
558 | fprintf (stderr, "FIXME\n"); | ||
559 | GNUNET_STATISTICS_update (GSE_stats, "# experiments running", | ||
560 | 1, GNUNET_NO); | ||
561 | } | ||
562 | |||
563 | /** | ||
564 | * Handle a response | ||
565 | * | ||
566 | * @param peer the source | ||
567 | * @param message the message | ||
568 | */ | ||
569 | static void handle_start_ack (const struct GNUNET_PeerIdentity *peer, | ||
570 | const struct GNUNET_MessageHeader *message) | ||
571 | { | ||
572 | |||
573 | } | ||
574 | |||
575 | /** | ||
576 | * Handle a response | ||
577 | * | ||
578 | * @param peer the source | ||
579 | * @param message the message | ||
580 | */ | ||
581 | static void handle_stop (const struct GNUNET_PeerIdentity *peer, | ||
582 | const struct GNUNET_MessageHeader *message) | ||
583 | { | ||
584 | |||
585 | } | ||
586 | |||
587 | /** | ||
550 | * Method called whenever a given peer connects. | 588 | * Method called whenever a given peer connects. |
551 | * | 589 | * |
552 | * @param cls closure | 590 | * @param cls closure |
@@ -619,6 +657,15 @@ core_receive_handler (void *cls, | |||
619 | case GNUNET_MESSAGE_TYPE_EXPERIMENTATION_RESPONSE: | 657 | case GNUNET_MESSAGE_TYPE_EXPERIMENTATION_RESPONSE: |
620 | handle_response (other, message); | 658 | handle_response (other, message); |
621 | break; | 659 | break; |
660 | case GNUNET_MESSAGE_TYPE_EXPERIMENTATION_START: | ||
661 | handle_start (other, message); | ||
662 | break; | ||
663 | case GNUNET_MESSAGE_TYPE_EXPERIMENTATION_START_ACK: | ||
664 | handle_start_ack (other, message); | ||
665 | break; | ||
666 | case GNUNET_MESSAGE_TYPE_EXPERIMENTATION_STOP: | ||
667 | handle_stop (other, message); | ||
668 | break; | ||
622 | default: | 669 | default: |
623 | break; | 670 | break; |
624 | } | 671 | } |
@@ -626,12 +673,88 @@ core_receive_handler (void *cls, | |||
626 | return GNUNET_OK; | 673 | return GNUNET_OK; |
627 | } | 674 | } |
628 | 675 | ||
676 | #define FAST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) | ||
629 | 677 | ||
630 | void | 678 | struct GNUNET_EXPERIMENTATION_start_message |
631 | GNUNET_EXPERIMENT_nodes_request_start (struct Node *n, struct Experiment *e) | ||
632 | { | 679 | { |
633 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Sending start request to peer `%s' for experiment `%s'\n"), | 680 | struct GNUNET_MessageHeader header; |
681 | }; | ||
682 | |||
683 | struct ExperimentStartCtx | ||
684 | { | ||
685 | struct ExperimentStartCtx *prev; | ||
686 | struct ExperimentStartCtx *next; | ||
687 | |||
688 | struct Node *n; | ||
689 | struct Experiment *e; | ||
690 | }; | ||
691 | |||
692 | size_t node_experiment_start_cb (void *cls, size_t bufsize, void *buf) | ||
693 | { | ||
694 | struct ExperimentStartCtx *e_ctx = cls; | ||
695 | struct GNUNET_EXPERIMENTATION_start_message msg; | ||
696 | |||
697 | GNUNET_CONTAINER_DLL_remove (e_ctx->n->e_req_head, e_ctx->n->e_req_tail, e_ctx); | ||
698 | e_ctx->n->cth = NULL; | ||
699 | if (NULL == buf) | ||
700 | { | ||
701 | GNUNET_free (e_ctx); | ||
702 | return 0; | ||
703 | } | ||
704 | |||
705 | size_t size = sizeof (struct GNUNET_EXPERIMENTATION_start_message); | ||
706 | msg.header.size = htons (size); | ||
707 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_EXPERIMENTATION_START); | ||
708 | |||
709 | memcpy (buf, &msg, size); | ||
710 | GNUNET_free (e_ctx); | ||
711 | return size; | ||
712 | } | ||
713 | |||
714 | int | ||
715 | GNUNET_EXPERIMENTATION_nodes_rts (struct Node *n) | ||
716 | { | ||
717 | if (NULL == n->cth) | ||
718 | return GNUNET_YES; | ||
719 | else | ||
720 | return GNUNET_NO; | ||
721 | |||
722 | } | ||
723 | |||
724 | /** | ||
725 | * Request a experiment to start with a node | ||
726 | * | ||
727 | * @return GNUNET_NO if core was busy with sending, GNUNET_OK otherwise | ||
728 | */ | ||
729 | int | ||
730 | GNUNET_EXPERIMENTATION_nodes_request_start (struct Node *n, struct Experiment *e) | ||
731 | { | ||
732 | struct ExperimentStartCtx *e_ctx; | ||
733 | |||
734 | if (NULL != n->cth) | ||
735 | { | ||
736 | GNUNET_break (0); /* should call rts before */ | ||
737 | return GNUNET_NO; | ||
738 | } | ||
739 | |||
740 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Sending experiment start request to peer `%s' for experiment `%s'\n"), | ||
634 | GNUNET_i2s(&n->id), e->name); | 741 | GNUNET_i2s(&n->id), e->name); |
742 | |||
743 | e_ctx = GNUNET_malloc (sizeof (struct ExperimentStartCtx)); | ||
744 | e_ctx->n = n; | ||
745 | e_ctx->e = e; | ||
746 | n->cth = GNUNET_CORE_notify_transmit_ready (ch, GNUNET_NO, 0, FAST_TIMEOUT, &n->id, | ||
747 | sizeof (struct GNUNET_EXPERIMENTATION_start_message), | ||
748 | &node_experiment_start_cb, e_ctx); | ||
749 | if (NULL == n->cth) | ||
750 | { | ||
751 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Cannot send experiment start request to peer `%s' for experiment `%s'\n"), | ||
752 | GNUNET_i2s(&n->id), e->name); | ||
753 | GNUNET_free (e_ctx); | ||
754 | } | ||
755 | GNUNET_CONTAINER_DLL_insert (n->e_req_head, n->e_req_tail, e_ctx); | ||
756 | |||
757 | return GNUNET_OK; | ||
635 | } | 758 | } |
636 | 759 | ||
637 | 760 | ||
diff --git a/src/experimentation/gnunet-daemon-experimentation_scheduler.c b/src/experimentation/gnunet-daemon-experimentation_scheduler.c index 795c993dd..5d2a51438 100644 --- a/src/experimentation/gnunet-daemon-experimentation_scheduler.c +++ b/src/experimentation/gnunet-daemon-experimentation_scheduler.c | |||
@@ -34,6 +34,7 @@ | |||
34 | enum ExperimentState | 34 | enum ExperimentState |
35 | { | 35 | { |
36 | NOT_RUNNING, | 36 | NOT_RUNNING, |
37 | BUSY, | ||
37 | REQUESTED, | 38 | REQUESTED, |
38 | STARTED, | 39 | STARTED, |
39 | STOPPED | 40 | STOPPED |
@@ -78,13 +79,27 @@ static void start_experiment (void *cls,const struct GNUNET_SCHEDULER_TaskContex | |||
78 | { | 79 | { |
79 | struct ScheduledExperiment *se = cls; | 80 | struct ScheduledExperiment *se = cls; |
80 | struct GNUNET_TIME_Relative end; | 81 | struct GNUNET_TIME_Relative end; |
82 | struct GNUNET_TIME_Relative backoff; | ||
83 | |||
81 | se->task = GNUNET_SCHEDULER_NO_TASK; | 84 | se->task = GNUNET_SCHEDULER_NO_TASK; |
82 | 85 | ||
86 | if (GNUNET_NO == GNUNET_EXPERIMENTATION_nodes_rts (se->n)) | ||
87 | { | ||
88 | se->state = BUSY; | ||
89 | backoff = GNUNET_TIME_UNIT_SECONDS; | ||
90 | backoff.rel_value += GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 1000); | ||
91 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Delaying start request to peer `%s' for `%s' for %llu ms\n", | ||
92 | GNUNET_i2s (&se->n->id), se->e->name, (unsigned long long) backoff.rel_value); | ||
93 | se->task = GNUNET_SCHEDULER_add_delayed (backoff, &start_experiment, se); | ||
94 | return; | ||
95 | } | ||
96 | else if (BUSY == se->state) | ||
97 | se->state = NOT_RUNNING; | ||
83 | 98 | ||
84 | if (NOT_RUNNING == se->state) | 99 | if (NOT_RUNNING == se->state) |
85 | { | 100 | { |
86 | /* Send start message */ | 101 | /* Send start message */ |
87 | GNUNET_EXPERIMENT_nodes_request_start (se->n, se->e); | 102 | GNUNET_EXPERIMENTATION_nodes_request_start (se->n, se->e); |
88 | se->state = REQUESTED; | 103 | se->state = REQUESTED; |
89 | se->task = GNUNET_SCHEDULER_add_delayed (EXP_RESPONSE_TIMEOUT, &request_timeout, se); | 104 | se->task = GNUNET_SCHEDULER_add_delayed (EXP_RESPONSE_TIMEOUT, &request_timeout, se); |
90 | 105 | ||
@@ -114,6 +129,7 @@ static void start_experiment (void *cls,const struct GNUNET_SCHEDULER_TaskContex | |||
114 | se->state = STOPPED; | 129 | se->state = STOPPED; |
115 | return; /* End of experiment is reached */ | 130 | return; /* End of experiment is reached */ |
116 | } | 131 | } |
132 | /* Reschedule */ | ||
117 | se->task = GNUNET_SCHEDULER_add_delayed (se->e->frequency, &start_experiment, se); | 133 | se->task = GNUNET_SCHEDULER_add_delayed (se->e->frequency, &start_experiment, se); |
118 | } | 134 | } |
119 | 135 | ||
@@ -127,6 +143,25 @@ static void start_experiment (void *cls,const struct GNUNET_SCHEDULER_TaskContex | |||
127 | * Start the scheduler component | 143 | * Start the scheduler component |
128 | */ | 144 | */ |
129 | void | 145 | void |
146 | GNUNET_EXPERIMENTATION_scheduler_handle_start (struct Node *n, struct Experiment *e) | ||
147 | { | ||
148 | |||
149 | } | ||
150 | |||
151 | |||
152 | /** | ||
153 | * Start the scheduler component | ||
154 | */ | ||
155 | void | ||
156 | GNUNET_EXPERIMENTATION_scheduler_handle_stop (struct Node *n, struct Experiment *e) | ||
157 | { | ||
158 | |||
159 | } | ||
160 | |||
161 | /** | ||
162 | * Start the scheduler component | ||
163 | */ | ||
164 | void | ||
130 | GNUNET_EXPERIMENTATION_scheduler_add (struct Node *n, struct Experiment *e) | 165 | GNUNET_EXPERIMENTATION_scheduler_add (struct Node *n, struct Experiment *e) |
131 | { | 166 | { |
132 | struct ScheduledExperiment *se; | 167 | struct ScheduledExperiment *se; |
diff --git a/src/experimentation/test_experimentation_clique_run.c b/src/experimentation/test_experimentation_clique_run.c new file mode 100644 index 000000000..35f48bce2 --- /dev/null +++ b/src/experimentation/test_experimentation_clique_run.c | |||
@@ -0,0 +1,363 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | (C) 2008--2013 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 src/experimentation/test_experimentation_clique_run.c | ||
23 | * @brief test case to run experiments with experimentation daemons in a clique | ||
24 | * @author Sree Harsha Totakura <sreeharsha@totakura.in> | ||
25 | * @author Matthias Wachs | ||
26 | */ | ||
27 | |||
28 | #include "platform.h" | ||
29 | #include "gnunet_common.h" | ||
30 | #include "gnunet_testbed_service.h" | ||
31 | |||
32 | |||
33 | /** | ||
34 | * Number of peers we want to start | ||
35 | */ | ||
36 | #define NUM_PEERS 2 | ||
37 | |||
38 | #define NUM_ISSUER 1 | ||
39 | |||
40 | #define NUM_EXPERIMENTS 2 | ||
41 | |||
42 | #define TEST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, (5 * NUM_PEERS) + 20) | ||
43 | |||
44 | /** | ||
45 | * Array of peers | ||
46 | */ | ||
47 | static struct GNUNET_TESTBED_Peer **peers; | ||
48 | |||
49 | /** | ||
50 | * Operation handle | ||
51 | */ | ||
52 | static struct GNUNET_TESTBED_Operation *op; | ||
53 | |||
54 | /** | ||
55 | * Shutdown task | ||
56 | */ | ||
57 | static GNUNET_SCHEDULER_TaskIdentifier shutdown_task; | ||
58 | |||
59 | /** | ||
60 | * Testing result | ||
61 | */ | ||
62 | static int result; | ||
63 | |||
64 | /** | ||
65 | * Counter for counting overlay connections | ||
66 | */ | ||
67 | static unsigned int overlay_connects; | ||
68 | |||
69 | /** | ||
70 | * Information we track for a peer in the testbed. | ||
71 | */ | ||
72 | struct ExperimentationPeer | ||
73 | { | ||
74 | /** | ||
75 | * Handle with testbed. | ||
76 | */ | ||
77 | struct GNUNET_TESTBED_Peer *daemon; | ||
78 | |||
79 | /** | ||
80 | * Testbed operation to connect to statistics service | ||
81 | */ | ||
82 | struct GNUNET_TESTBED_Operation *stat_op; | ||
83 | |||
84 | /** | ||
85 | * Handle to the statistics service | ||
86 | */ | ||
87 | struct GNUNET_STATISTICS_Handle *sh; | ||
88 | |||
89 | unsigned int active_nodes; | ||
90 | unsigned int requested_nodes; | ||
91 | unsigned int inactive_nodes; | ||
92 | unsigned int issuer; | ||
93 | unsigned int experiments_active; | ||
94 | unsigned int experiments_running; | ||
95 | }; | ||
96 | |||
97 | |||
98 | struct ExperimentationPeer ph[NUM_PEERS]; | ||
99 | |||
100 | /** | ||
101 | * Shutdown nicely | ||
102 | * | ||
103 | * @param cls NULL | ||
104 | * @param tc the task context | ||
105 | */ | ||
106 | static void | ||
107 | do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
108 | { | ||
109 | unsigned int peer; | ||
110 | shutdown_task = GNUNET_SCHEDULER_NO_TASK; | ||
111 | |||
112 | for (peer = 0; peer < NUM_PEERS; peer++) | ||
113 | { | ||
114 | if (NULL != ph[peer].stat_op) | ||
115 | GNUNET_TESTBED_operation_done (ph[peer].stat_op); | ||
116 | ph[peer].stat_op = NULL; | ||
117 | } | ||
118 | |||
119 | if (NULL != op) | ||
120 | { | ||
121 | GNUNET_TESTBED_operation_done (op); | ||
122 | op = NULL; | ||
123 | } | ||
124 | GNUNET_SCHEDULER_shutdown (); | ||
125 | } | ||
126 | |||
127 | /** | ||
128 | * Controller event callback | ||
129 | * | ||
130 | * @param cls NULL | ||
131 | * @param event the controller event | ||
132 | */ | ||
133 | static void | ||
134 | controller_event_cb (void *cls, | ||
135 | const struct GNUNET_TESTBED_EventInformation *event) | ||
136 | { | ||
137 | switch (event->type) | ||
138 | { | ||
139 | case GNUNET_TESTBED_ET_CONNECT: | ||
140 | overlay_connects++; | ||
141 | if ((NUM_PEERS * (NUM_PEERS - 1)) == overlay_connects) | ||
142 | { | ||
143 | result = GNUNET_OK; | ||
144 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "All %u peers connected \n", NUM_PEERS); | ||
145 | if (GNUNET_SCHEDULER_NO_TASK != shutdown_task) | ||
146 | { | ||
147 | GNUNET_SCHEDULER_cancel (shutdown_task); | ||
148 | } | ||
149 | shutdown_task = GNUNET_SCHEDULER_add_delayed (TEST_TIMEOUT, do_shutdown, NULL); | ||
150 | } | ||
151 | break; | ||
152 | case GNUNET_TESTBED_ET_OPERATION_FINISHED: | ||
153 | break; | ||
154 | default: | ||
155 | GNUNET_break (0); | ||
156 | result = GNUNET_SYSERR; | ||
157 | GNUNET_SCHEDULER_cancel (shutdown_task); | ||
158 | shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | ||
159 | } | ||
160 | } | ||
161 | |||
162 | static void | ||
163 | check_end () | ||
164 | { | ||
165 | |||
166 | static int last_experiments_value = 0; | ||
167 | unsigned int peer; | ||
168 | unsigned int t_running_experiments = 0; | ||
169 | |||
170 | for (peer = 0; peer < NUM_PEERS; peer++) | ||
171 | { | ||
172 | t_running_experiments += ph[peer].experiments_running; | ||
173 | } | ||
174 | |||
175 | if (last_experiments_value < t_running_experiments) | ||
176 | fprintf (stderr, "."); | ||
177 | last_experiments_value = t_running_experiments; | ||
178 | |||
179 | if (t_running_experiments == (NUM_PEERS * NUM_EXPERIMENTS)) | ||
180 | { | ||
181 | fprintf (stderr, "\n"); | ||
182 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "All %u peers are running experiments\n", NUM_PEERS); | ||
183 | GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | ||
184 | } | ||
185 | } | ||
186 | |||
187 | |||
188 | |||
189 | /** | ||
190 | * Callback function to process statistic values. | ||
191 | * | ||
192 | * @param cls struct StatsContext | ||
193 | * @param subsystem name of subsystem that created the statistic | ||
194 | * @param name the name of the datum | ||
195 | * @param value the current value | ||
196 | * @param is_persistent GNUNET_YES if the value is persistent, GNUNET_NO if not | ||
197 | * @return GNUNET_OK to continue, GNUNET_SYSERR to abort iteration | ||
198 | */ | ||
199 | static int | ||
200 | stat_iterator (void *cls, const char *subsystem, const char *name, | ||
201 | uint64_t value, int is_persistent) | ||
202 | { | ||
203 | struct ExperimentationPeer *peer = cls; | ||
204 | |||
205 | if (0 == strcmp (name, "# experiments active")) | ||
206 | { | ||
207 | peer->experiments_active = value; | ||
208 | } | ||
209 | |||
210 | if (0 == strcmp (name, "# experiments running")) | ||
211 | { | ||
212 | peer->experiments_running = value; | ||
213 | } | ||
214 | |||
215 | check_end (); | ||
216 | |||
217 | return GNUNET_OK; | ||
218 | } | ||
219 | |||
220 | /** | ||
221 | * Called after successfully opening a connection to a peer's statistics | ||
222 | * service; we register statistics monitoring here. | ||
223 | * | ||
224 | * @param cls the callback closure from functions generating an operation | ||
225 | * @param op the operation that has been finished | ||
226 | * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter() | ||
227 | * @param emsg error message in case the operation has failed; will be NULL if | ||
228 | * operation has executed successfully. | ||
229 | */ | ||
230 | static void | ||
231 | stat_comp_cb (void *cls, struct GNUNET_TESTBED_Operation *op, | ||
232 | void *ca_result, const char *emsg ) | ||
233 | { | ||
234 | //struct GNUNET_STATISTICS_Handle *sh = ca_result; | ||
235 | struct ExperimentationPeer *peer = cls; | ||
236 | |||
237 | if (NULL != emsg) | ||
238 | { | ||
239 | GNUNET_break (0); | ||
240 | return; | ||
241 | } | ||
242 | |||
243 | GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch | ||
244 | (peer->sh, "experimentation", "# experiments active", | ||
245 | stat_iterator, peer)); | ||
246 | GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch | ||
247 | (peer->sh, "experimentation", "# experiments running", | ||
248 | stat_iterator, peer)); | ||
249 | } | ||
250 | |||
251 | /** | ||
252 | * Called to open a connection to the peer's statistics | ||
253 | * | ||
254 | * @param cls peer context | ||
255 | * @param cfg configuration of the peer to connect to; will be available until | ||
256 | * GNUNET_TESTBED_operation_done() is called on the operation returned | ||
257 | * from GNUNET_TESTBED_service_connect() | ||
258 | * @return service handle to return in 'op_result', NULL on error | ||
259 | */ | ||
260 | static void * | ||
261 | stat_connect_adapter (void *cls, | ||
262 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
263 | { | ||
264 | struct ExperimentationPeer *peer = cls; | ||
265 | peer->sh = GNUNET_STATISTICS_create ("experimentation", cfg); | ||
266 | if (NULL == peer->sh) | ||
267 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to create statistics \n"); | ||
268 | return peer->sh; | ||
269 | } | ||
270 | |||
271 | |||
272 | /** | ||
273 | * Called to disconnect from peer's statistics service | ||
274 | * | ||
275 | * @param cls peer context | ||
276 | * @param op_result service handle returned from the connect adapter | ||
277 | */ | ||
278 | static void | ||
279 | stat_disconnect_adapter (void *cls, void *op_result) | ||
280 | { | ||
281 | struct ExperimentationPeer *peer = cls; | ||
282 | GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch_cancel | ||
283 | (peer->sh, "experimentation", "# experiments active", | ||
284 | stat_iterator, peer)); | ||
285 | GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch_cancel | ||
286 | (peer->sh, "experimentation", "# experiments running", | ||
287 | stat_iterator, peer)); | ||
288 | GNUNET_STATISTICS_destroy (op_result, GNUNET_NO); | ||
289 | peer->sh = NULL; | ||
290 | } | ||
291 | |||
292 | |||
293 | |||
294 | /** | ||
295 | * Signature of a main function for a testcase. | ||
296 | * | ||
297 | * @param cls closure | ||
298 | * @param num_peers number of peers in 'peers' | ||
299 | * @param peers_ handle to peers run in the testbed | ||
300 | * @param links_succeeded the number of overlay link connection attempts that | ||
301 | * succeeded | ||
302 | * @param links_failed the number of overlay link connection attempts that | ||
303 | * failed | ||
304 | */ | ||
305 | static void | ||
306 | test_master (void *cls, unsigned int num_peers, | ||
307 | struct GNUNET_TESTBED_Peer **peers_, | ||
308 | unsigned int links_succeeded, | ||
309 | unsigned int links_failed) | ||
310 | { | ||
311 | unsigned int peer; | ||
312 | |||
313 | GNUNET_assert (NULL == cls); | ||
314 | GNUNET_assert (NUM_PEERS == num_peers); | ||
315 | GNUNET_assert (NULL != peers_); | ||
316 | for (peer = 0; peer < num_peers; peer++) | ||
317 | { | ||
318 | GNUNET_assert (NULL != peers_[peer]); | ||
319 | /* Connect to peer's statistic service */ | ||
320 | ph[peer].stat_op = GNUNET_TESTBED_service_connect (NULL, | ||
321 | peers_[peer], "statistics", | ||
322 | &stat_comp_cb, &ph[peer], | ||
323 | &stat_connect_adapter, | ||
324 | &stat_disconnect_adapter, | ||
325 | &ph[peer]); | ||
326 | |||
327 | } | ||
328 | peers = peers_; | ||
329 | overlay_connects = 0; | ||
330 | op = GNUNET_TESTBED_overlay_configure_topology (NULL, NUM_PEERS, peers, NULL, | ||
331 | NULL, | ||
332 | NULL, | ||
333 | GNUNET_TESTBED_TOPOLOGY_CLIQUE, | ||
334 | /* GNUNET_TESTBED_TOPOLOGY_ERDOS_RENYI, */ | ||
335 | /* NUM_PEERS, */ | ||
336 | GNUNET_TESTBED_TOPOLOGY_OPTION_END); | ||
337 | GNUNET_assert (NULL != op); | ||
338 | shutdown_task = GNUNET_SCHEDULER_add_delayed (TEST_TIMEOUT, do_shutdown, NULL); | ||
339 | } | ||
340 | |||
341 | |||
342 | /** | ||
343 | * Main function | ||
344 | */ | ||
345 | int | ||
346 | main (int argc, char **argv) | ||
347 | { | ||
348 | uint64_t event_mask; | ||
349 | |||
350 | result = GNUNET_SYSERR; | ||
351 | event_mask = 0; | ||
352 | event_mask |= (1LL << GNUNET_TESTBED_ET_CONNECT); | ||
353 | event_mask |= (1LL << GNUNET_TESTBED_ET_OPERATION_FINISHED); | ||
354 | (void) GNUNET_TESTBED_test_run ("test_experimentation_clique_run", | ||
355 | "test_experimentation_clique.conf", NUM_PEERS, | ||
356 | event_mask, &controller_event_cb, NULL, | ||
357 | &test_master, NULL); | ||
358 | if (GNUNET_OK != result) | ||
359 | return 1; | ||
360 | return 0; | ||
361 | } | ||
362 | |||
363 | /* end of test_experimentation_clique_run.c */ | ||