2 This file is part of GNUnet.
3 Copyright (C) 2009, 2012 GNUnet e.V.
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.
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.
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/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
21 * @file topology/test_gnunet_daemon_topology.c
22 * @brief testcase for topology maintenance code
23 * @author Christian Grothoff
27 #include "gnunet_testbed_service.h"
28 #include "gnunet_statistics_service.h"
34 * The threshold defines the number of connection that are needed
35 * for one peer to pass the test. Be aware that setting NUM_PEERS
36 * too high can cause bandwidth problems for the testing peers.
37 * Normal should be 5KB/s per peer. See gnunet-config -s ats.
39 #define THRESHOLD NUM_PEERS / 2
42 * How long until we give up on connecting the peers?
44 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60)
47 * Store manual connections.
49 static unsigned int connect_left;
52 * Result of the testcase.
57 * Peers that reached the threshold of connections.
59 static int checked_peers;
64 struct GNUNET_TESTBED_Operation *op[NUM_PEERS];
67 * Timeout for testcase.
69 static struct GNUNET_SCHEDULER_Task *timeout_tid;
72 * Peer context for every testbed peer.
77 struct GNUNET_STATISTICS_Handle *statistics;
79 int reported; /* GNUNET_NO | GNUNET_YES */
84 shutdown_task (void *cls)
88 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
89 "Shutting down testcase\n");
91 for (i = 0; i < NUM_PEERS; i++)
94 GNUNET_TESTBED_operation_done (op[i]);
97 if (NULL != timeout_tid)
98 GNUNET_SCHEDULER_cancel (timeout_tid);
103 timeout_task (void *cls)
106 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
107 "Testcase timeout\n");
109 result = GNUNET_SYSERR;
110 GNUNET_SCHEDULER_shutdown ();
115 * The function is called every time the topology of connected
116 * peers to a peer changes.
119 statistics_iterator (void *cls,
120 const char *subsystem,
125 struct peerctx *p_ctx = (struct peerctx*) cls;
127 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
128 "Peer %d: %s = %llu\n",
131 (unsigned long long) value);
133 if (p_ctx->connections < value)
134 p_ctx->connections = value;
136 if ((THRESHOLD <= value) && (GNUNET_NO == p_ctx->reported))
138 p_ctx->reported = GNUNET_YES;
140 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
141 "Peer %d successfully connected to at least %d peers once.\n",
145 if (checked_peers == NUM_PEERS)
147 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
148 "Test OK: All peers have connected to %d peers once.\n",
151 GNUNET_SCHEDULER_shutdown ();
160 ca_statistics (void *cls,
161 const struct GNUNET_CONFIGURATION_Handle *cfg)
163 return GNUNET_STATISTICS_create ("topology", cfg);
168 da_statistics (void *cls,
171 struct peerctx *p_ctx = (struct peerctx *) cls;
173 GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch_cancel
174 (p_ctx->statistics, "topology", "# peers connected",
175 statistics_iterator, p_ctx));
177 GNUNET_STATISTICS_destroy (p_ctx->statistics, GNUNET_NO);
178 p_ctx->statistics = NULL;
185 service_connect_complete (void *cls,
186 struct GNUNET_TESTBED_Operation *op,
191 struct peerctx *p_ctx = (struct peerctx*) cls;
193 if (NULL == ca_result)
194 GNUNET_SCHEDULER_shutdown ();
196 p_ctx->statistics = ca_result;
198 ret = GNUNET_STATISTICS_watch (ca_result,
204 if (GNUNET_NO == ret)
205 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
206 "call to GNUNET_STATISTICS_watch() failed\n");
211 notify_connect_complete (void *cls,
212 struct GNUNET_TESTBED_Operation *op,
215 GNUNET_TESTBED_operation_done (op);
218 fprintf (stderr, "Failed to connect two peers: %s\n", emsg);
219 result = GNUNET_SYSERR;
220 GNUNET_SCHEDULER_shutdown ();
228 do_connect (void *cls,
229 struct GNUNET_TESTBED_RunHandle *h,
230 unsigned int num_peers,
231 struct GNUNET_TESTBED_Peer **peers,
232 unsigned int links_succeeded,
233 unsigned int links_failed)
236 struct peerctx *p_ctx;
238 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
239 "Threshold is set to %d.\n",
242 GNUNET_assert (NUM_PEERS == num_peers);
244 for (i = 0; i < NUM_PEERS; i++)
246 p_ctx = GNUNET_new (struct peerctx);
248 p_ctx->connections = 0;
249 p_ctx->reported = GNUNET_NO;
251 if (i < NUM_PEERS - 1)
254 GNUNET_TESTBED_overlay_connect (NULL,
255 ¬ify_connect_complete, NULL,
256 peers[i], peers[i + 1]);
260 GNUNET_TESTBED_service_connect (cls,
263 service_connect_complete,
264 p_ctx, /* cls of completion cb */
265 ca_statistics, /* connect adapter */
266 da_statistics, /* disconnect adapter */
270 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
272 GNUNET_SCHEDULER_add_delayed (TIMEOUT,
279 main (int argc, char *argv[])
281 result = GNUNET_SYSERR;
284 (void) GNUNET_TESTBED_test_run ("test-gnunet-daemon-topology",
285 "test_gnunet_daemon_topology_data.conf",
289 GNUNET_DISK_directory_remove ("/tmp/test-gnunet-topology");
291 return (GNUNET_OK != result) ? 1 : 0;
295 /* end of test_gnunet_daemon_topology.c */