/*
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