123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- /*
- This file is part of GNUnet.
- Copyright (C) 2009, 2012 GNUnet e.V.
- GNUnet is free software: you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License,
- or (at your option) any later version.
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- SPDX-License-Identifier: AGPL3.0-or-later
- */
- /**
- * @file topology/test_gnunet_daemon_topology.c
- * @brief testcase for topology maintenance code
- * @author Christian Grothoff
- * @author xrs
- */
- #include "platform.h"
- #include "gnunet_testbed_service.h"
- #include "gnunet_statistics_service.h"
- #define NUM_PEERS 8
- /*
- * The threshold defines the number of connection that are needed
- * for one peer to pass the test. Be aware that setting NUM_PEERS
- * too high can cause bandwidth problems for the testing peers.
- * Normal should be 5KB/s per peer. See gnunet-config -s ats.
- * schanzen 12/2019: This _only_ makes sense if we connect to the
- * actual network as in the test we do not connect to more than 1 peer.
- * => reducing to 1 for now, was NUM_PEERS / 2
- */
- #define THRESHOLD 1
- /**
- * How long until we give up on connecting the peers?
- */
- #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60)
- /*
- * Store manual connections.
- */
- static unsigned int connect_left;
- /*
- * Result of the testcase.
- */
- static int result;
- /*
- * Peers that reached the threshold of connections.
- */
- static int checked_peers;
- /*
- * Testbed operations.
- */
- struct GNUNET_TESTBED_Operation *op[NUM_PEERS];
- /*
- * Timeout for testcase.
- */
- static struct GNUNET_SCHEDULER_Task *timeout_tid;
- /*
- * Peer context for every testbed peer.
- */
- struct peerctx
- {
- int index;
- struct GNUNET_STATISTICS_Handle *statistics;
- int connections;
- int reported; /* GNUNET_NO | GNUNET_YES */
- };
- static void
- shutdown_task (void *cls)
- {
- unsigned int i;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Shutting down testcase\n");
- for (i = 0; i < NUM_PEERS; i++)
- {
- if (NULL != op[i])
- GNUNET_TESTBED_operation_done (op[i]);
- }
- if (NULL != timeout_tid)
- GNUNET_SCHEDULER_cancel (timeout_tid);
- }
- static void
- timeout_task (void *cls)
- {
- timeout_tid = NULL;
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Testcase timeout\n");
- result = GNUNET_SYSERR;
- GNUNET_SCHEDULER_shutdown ();
- }
- /*
- * The function is called every time the topology of connected
- * peers to a peer changes.
- */
- int
- statistics_iterator (void *cls,
- const char *subsystem,
- const char *name,
- uint64_t value,
- int is_persistent)
- {
- struct peerctx *p_ctx = (struct peerctx*) cls;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Peer %d: %s = %llu\n",
- p_ctx->index,
- name,
- (unsigned long long) value);
- if (p_ctx->connections < value)
- p_ctx->connections = value;
- if ((THRESHOLD <= value) && (GNUNET_NO == p_ctx->reported))
- {
- p_ctx->reported = GNUNET_YES;
- checked_peers++;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Peer %d successfully connected to at least %d peers once.\n",
- p_ctx->index,
- THRESHOLD);
- if (checked_peers == NUM_PEERS)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Test OK: All peers have connected to %d peers once.\n",
- THRESHOLD);
- result = GNUNET_YES;
- GNUNET_SCHEDULER_shutdown ();
- }
- }
- return GNUNET_YES;
- }
- static void *
- ca_statistics (void *cls,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
- {
- return GNUNET_STATISTICS_create ("topology", cfg);
- }
- void
- da_statistics (void *cls,
- void *op_result)
- {
- struct peerctx *p_ctx = (struct peerctx *) cls;
- GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch_cancel
- (p_ctx->statistics, "topology", "# peers connected",
- statistics_iterator, p_ctx));
- GNUNET_STATISTICS_destroy (p_ctx->statistics, GNUNET_NO);
- p_ctx->statistics = NULL;
- GNUNET_free (p_ctx);
- }
- static void
- service_connect_complete (void *cls,
- struct GNUNET_TESTBED_Operation *op,
- void *ca_result,
- const char *emsg)
- {
- int ret;
- struct peerctx *p_ctx = (struct peerctx*) cls;
- if (NULL == ca_result)
- GNUNET_SCHEDULER_shutdown ();
- p_ctx->statistics = ca_result;
- ret = GNUNET_STATISTICS_watch (ca_result,
- "topology",
- "# peers connected",
- statistics_iterator,
- p_ctx);
- if (GNUNET_NO == ret)
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "call to GNUNET_STATISTICS_watch() failed\n");
- }
- static void
- notify_connect_complete (void *cls,
- struct GNUNET_TESTBED_Operation *op,
- const char *emsg)
- {
- GNUNET_TESTBED_operation_done (op);
- if (NULL != emsg)
- {
- fprintf (stderr, "Failed to connect two peers: %s\n", emsg);
- result = GNUNET_SYSERR;
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
- connect_left--;
- }
- static void
- do_connect (void *cls,
- struct GNUNET_TESTBED_RunHandle *h,
- unsigned int num_peers,
- struct GNUNET_TESTBED_Peer **peers,
- unsigned int links_succeeded,
- unsigned int links_failed)
- {
- unsigned int i;
- struct peerctx *p_ctx;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Threshold is set to %d.\n",
- THRESHOLD);
- GNUNET_assert (NUM_PEERS == num_peers);
- for (i = 0; i < NUM_PEERS; i++)
- {
- p_ctx = GNUNET_new (struct peerctx);
- p_ctx->index = i;
- p_ctx->connections = 0;
- p_ctx->reported = GNUNET_NO;
- if (i < NUM_PEERS - 1)
- {
- connect_left++;
- GNUNET_TESTBED_overlay_connect (NULL,
- ¬ify_connect_complete, NULL,
- peers[i], peers[i + 1]);
- }
- op[i] =
- GNUNET_TESTBED_service_connect (cls,
- peers[i],
- "statistics",
- service_connect_complete,
- p_ctx, /* cls of completion cb */
- ca_statistics, /* connect adapter */
- da_statistics, /* disconnect adapter */
- p_ctx);
- }
- GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
- timeout_tid =
- GNUNET_SCHEDULER_add_delayed (TIMEOUT,
- &timeout_task,
- NULL);
- }
- int
- main (int argc, char *argv[])
- {
- result = GNUNET_SYSERR;
- checked_peers = 0;
- (void) GNUNET_TESTBED_test_run ("test-gnunet-daemon-topology",
- "test_gnunet_daemon_topology_data.conf",
- NUM_PEERS,
- 0, NULL, NULL,
- &do_connect, NULL);
- GNUNET_DISK_directory_remove ("/tmp/test-gnunet-topology");
- return (GNUNET_OK != result) ? 1 : 0;
- }
- /* end of test_gnunet_daemon_topology.c */
|