/* 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 . 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. */ #define THRESHOLD NUM_PEERS/2 /** * 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;iindex, 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;iindex = i; p_ctx->connections = 0; p_ctx->reported = GNUNET_NO; if (i