aboutsummaryrefslogtreecommitdiff
path: root/src/topology/test_gnunet_daemon_topology.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/topology/test_gnunet_daemon_topology.c')
-rw-r--r--src/topology/test_gnunet_daemon_topology.c243
1 files changed, 215 insertions, 28 deletions
diff --git a/src/topology/test_gnunet_daemon_topology.c b/src/topology/test_gnunet_daemon_topology.c
index 7242fcf43..5359c280e 100644
--- a/src/topology/test_gnunet_daemon_topology.c
+++ b/src/topology/test_gnunet_daemon_topology.c
@@ -2,65 +2,218 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2009, 2012 GNUnet e.V. 3 Copyright (C) 2009, 2012 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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20/** 18/**
21 * @file topology/test_gnunet_daemon_topology.c 19 * @file topology/test_gnunet_daemon_topology.c
22 * @brief testcase for topology maintenance code 20 * @brief testcase for topology maintenance code
21 * @author Christian Grothoff
22 * @author xrs
23 */ 23 */
24#include "platform.h" 24#include "platform.h"
25#include "gnunet_testbed_service.h" 25#include "gnunet_testbed_service.h"
26#include "gnunet_statistics_service.h"
26 27
27 28
28#define NUM_PEERS 8 29#define NUM_PEERS 8
29 30
31/*
32 * The threshold defines the number of connection that are needed
33 * for one peer to pass the test. Be aware that setting NUM_PEERS
34 * too high can cause bandwidth problems for the testing peers.
35 * Normal should be 5KB/s per peer. See gnunet-config -s ats.
36 */
37#define THRESHOLD NUM_PEERS/2
38
30/** 39/**
31 * How long until we give up on connecting the peers? 40 * How long until we give up on connecting the peers?
32 */ 41 */
33#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 600) 42#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60)
34 43
44/*
45 * Store manual connections.
46 */
47static unsigned int connect_left;
35 48
36static int ok; 49/*
50 * Result of the testcase.
51 */
52static int result;
37 53
38static unsigned int connect_left; 54/*
55 * Peers that reached the threshold of connections.
56 */
57static int checked_peers;
58
59/*
60 * Testbed operations.
61 */
62struct GNUNET_TESTBED_Operation *op[NUM_PEERS];
63
64/*
65 * Timeout for testcase.
66 */
67static struct GNUNET_SCHEDULER_Task *timeout_tid;
68
69/*
70 * Peer context for every testbed peer.
71 */
72struct peerctx
73{
74 int index;
75 struct GNUNET_STATISTICS_Handle *statistics;
76 int connections;
77 int reported; /* GNUNET_NO | GNUNET_YES */
78};
79
80
81static void
82shutdown_task (void *cls)
83{
84 unsigned int i;
85
86 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
87 "Shutting down testcase\n");
39 88
89 for (i=0;i<NUM_PEERS;i++) {
90 if (NULL != op[i])
91 GNUNET_TESTBED_operation_done (op[i]);
92 }
93
94 if (NULL != timeout_tid)
95 GNUNET_SCHEDULER_cancel (timeout_tid);
96}
97
98static void
99timeout_task (void *cls)
100{
101 timeout_tid = NULL;
102 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
103 "Testcase timeout\n");
104
105 result = GNUNET_SYSERR;
106 GNUNET_SCHEDULER_shutdown();
107}
108
109/*
110 * The function is called every time the topology of connected
111 * peers to a peer changes.
112 */
113int
114statistics_iterator (void *cls,
115 const char *subsystem,
116 const char *name,
117 uint64_t value,
118 int is_persistent)
119{
120 struct peerctx *p_ctx = (struct peerctx*) cls;
121
122 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
123 "Peer %d: %s = %llu\n",
124 p_ctx->index,
125 name,
126 (unsigned long long) value);
127
128 if (p_ctx->connections < value)
129 p_ctx->connections = value;
130
131 if (THRESHOLD <= value && GNUNET_NO == p_ctx->reported) {
132 p_ctx->reported = GNUNET_YES;
133 checked_peers++;
134 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
135 "Peer %d successfully connected to at least %d peers once.\n",
136 p_ctx->index,
137 THRESHOLD);
138
139 if (checked_peers == NUM_PEERS) {
140 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
141 "Test OK: All peers have connected to %d peers once.\n",
142 THRESHOLD);
143 result = GNUNET_YES;
144 GNUNET_SCHEDULER_shutdown();
145 }
146 }
147
148 return GNUNET_YES;
149}
150
151static void *
152ca_statistics (void *cls,
153 const struct GNUNET_CONFIGURATION_Handle *cfg)
154{
155 return GNUNET_STATISTICS_create ("topology", cfg);
156}
157
158
159void
160da_statistics (void *cls,
161 void *op_result)
162{
163 struct peerctx *p_ctx = (struct peerctx *) cls;
164
165 GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch_cancel
166 (p_ctx->statistics, "topology", "# peers connected",
167 statistics_iterator, p_ctx));
168
169 GNUNET_STATISTICS_destroy (p_ctx->statistics, GNUNET_NO);
170 p_ctx->statistics = NULL;
171
172 GNUNET_free (p_ctx);
173}
174
175
176static void
177service_connect_complete (void *cls,
178 struct GNUNET_TESTBED_Operation *op,
179 void *ca_result,
180 const char *emsg)
181{
182 int ret;
183 struct peerctx *p_ctx = (struct peerctx*) cls;
184
185 if (NULL == ca_result)
186 GNUNET_SCHEDULER_shutdown();
187
188 p_ctx->statistics = ca_result;
189
190 ret = GNUNET_STATISTICS_watch (ca_result,
191 "topology",
192 "# peers connected",
193 statistics_iterator,
194 p_ctx);
195
196 if (GNUNET_NO == ret)
197 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
198 "call to GNUNET_STATISTICS_watch() failed\n");
199}
40 200
41static void 201static void
42notify_connect_complete (void *cls, 202notify_connect_complete (void *cls,
43 struct GNUNET_TESTBED_Operation *op, 203 struct GNUNET_TESTBED_Operation *op,
44 const char *emsg) 204 const char *emsg)
45{ 205{
46 GNUNET_TESTBED_operation_done (op); 206 GNUNET_TESTBED_operation_done (op);
47 if (NULL != emsg) 207 if (NULL != emsg)
48 { 208 {
49 FPRINTF (stderr, "Failed to connect two peers: %s\n", emsg); 209 FPRINTF (stderr, "Failed to connect two peers: %s\n", emsg);
210 result = GNUNET_SYSERR;
50 GNUNET_SCHEDULER_shutdown (); 211 GNUNET_SCHEDULER_shutdown ();
51 ok = 1;
52 return; 212 return;
53 } 213 }
54 connect_left--; 214 connect_left--;
55 if (0 == connect_left)
56 {
57 /* FIXME: check that topology adds a few more links
58 * in addition to those that were seeded */
59 GNUNET_SCHEDULER_shutdown ();
60 }
61} 215}
62 216
63
64static void 217static void
65do_connect (void *cls, 218do_connect (void *cls,
66 struct GNUNET_TESTBED_RunHandle *h, 219 struct GNUNET_TESTBED_RunHandle *h,
@@ -70,28 +223,62 @@ do_connect (void *cls,
70 unsigned int links_failed) 223 unsigned int links_failed)
71{ 224{
72 unsigned int i; 225 unsigned int i;
226 struct peerctx *p_ctx;
227
228 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
229 "Threshold is set to %d.\n",
230 THRESHOLD);
73 231
74 GNUNET_assert (NUM_PEERS == num_peers); 232 GNUNET_assert (NUM_PEERS == num_peers);
75 for (i=0;i<num_peers-1;i++) 233
234 for (i=0;i<NUM_PEERS;i++)
76 { 235 {
77 connect_left++; 236 p_ctx = GNUNET_new (struct peerctx);
78 GNUNET_TESTBED_overlay_connect (NULL, 237 p_ctx->index = i;
79 &notify_connect_complete, NULL, 238 p_ctx->connections = 0;
80 peers[i], peers[i+1]); 239 p_ctx->reported = GNUNET_NO;
240
241 if (i<NUM_PEERS-1) {
242 connect_left++;
243 GNUNET_TESTBED_overlay_connect (NULL,
244 &notify_connect_complete, NULL,
245 peers[i], peers[i+1]);
246 }
247
248 op[i] =
249 GNUNET_TESTBED_service_connect (cls,
250 peers[i],
251 "statistics",
252 service_connect_complete,
253 p_ctx, /* cls of completion cb */
254 ca_statistics, /* connect adapter */
255 da_statistics, /* disconnect adapter */
256 p_ctx);
257
81 } 258 }
259
260 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
261 timeout_tid =
262 GNUNET_SCHEDULER_add_delayed (TIMEOUT,
263 &timeout_task,
264 NULL);
82} 265}
83 266
84 267
85int 268int
86main (int argc, char *argv[]) 269main (int argc, char *argv[])
87{ 270{
271 result = GNUNET_SYSERR;
272 checked_peers = 0;
273
88 (void) GNUNET_TESTBED_test_run ("test-gnunet-daemon-topology", 274 (void) GNUNET_TESTBED_test_run ("test-gnunet-daemon-topology",
89 "test_gnunet_daemon_topology_data.conf", 275 "test_gnunet_daemon_topology_data.conf",
90 NUM_PEERS, 276 NUM_PEERS,
91 0, NULL, NULL, 277 0, NULL, NULL,
92 &do_connect, NULL); 278 &do_connect, NULL);
93 GNUNET_DISK_directory_remove ("/tmp/test-gnunet-topology"); 279 GNUNET_DISK_directory_remove ("/tmp/test-gnunet-topology");
94 return ok; 280
281 return (GNUNET_OK != result) ? 1 : 0;
95} 282}
96 283
97/* end of test_gnunet_daemon_topology.c */ 284/* end of test_gnunet_daemon_topology.c */