/*
This file is part of GNUnet.
(C) 2011 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, 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
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNUnet; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
/**
* @file mesh/test_mesh_small.c
*
* @brief Test for the mesh service: retransmission of traffic.
*/
#include <stdio.h>
#include "platform.h"
#include "gnunet_testing_lib.h"
#include "gnunet_mesh_service.h"
#include <gauger.h>
#define VERBOSE GNUNET_YES
#define REMOVE_DIR GNUNET_YES
struct MeshPeer
{
struct MeshPeer *prev;
struct MeshPeer *next;
struct GNUNET_TESTING_Daemon *daemon;
struct GNUNET_MESH_Handle *mesh_handle;
};
/**
* How long until we give up on connecting the peers?
*/
#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1500)
/**
* Time to wait for stuff that should be rather fast
*/
#define SHORT_TIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300)
/**
* DIFFERENT TESTS TO RUN
*/
#define SETUP 0
#define UNICAST 1
#define MULTICAST 2
#define SPEED 3
#define SPEED_ACK 4
/**
* Which test are we running?
*/
static int test;
/**
* How many events have happened
*/
static int ok;
static int peers_in_tunnel;
static int peers_responded;
static int data_sent;
static int data_received;
static int data_ack;
/**
* Be verbose
*/
static int verbose;
/**
* Total number of peers in the test.
*/
static unsigned long long num_peers;
/**
* Global configuration file
*/
static struct GNUNET_CONFIGURATION_Handle *testing_cfg;
/**
* Total number of currently running peers.
*/
static unsigned long long peers_running;
/**
* Total number of connections in the whole network.
*/
static unsigned int total_connections;
/**
* The currently running peer group.
*/
static struct GNUNET_TESTING_PeerGroup *pg;
/**
* File to report results to.
*/
static struct GNUNET_DISK_FileHandle *output_file;
/**
* File to log connection info, statistics to.
*/
static struct GNUNET_DISK_FileHandle *data_file;
/**
* How many data points to capture before triggering next round?
*/
static struct GNUNET_TIME_Relative wait_time;
/**
* Task called to disconnect peers.
*/
static GNUNET_SCHEDULER_TaskIdentifier disconnect_task;
/**
* Task To perform tests
*/
static GNUNET_SCHEDULER_TaskIdentifier test_task;
/**
* Task called to shutdown test.
*/
static GNUNET_SCHEDULER_TaskIdentifier shutdown_handle;
static char *topology_file;
static struct GNUNET_TESTING_Daemon *d1;
static GNUNET_PEER_Id pid1;
static struct GNUNET_TESTING_Daemon *d2;
static struct GNUNET_TESTING_Daemon *d3;
static struct GNUNET_MESH_Handle *h1;
static struct GNUNET_MESH_Handle *h2;
static struct GNUNET_MESH_Handle *h3;
static struct GNUNET_MESH_Tunnel *t;
static struct GNUNET_MESH_Tunnel *incoming_t;
static struct GNUNET_MESH_Tunnel *incoming_t2;
static struct GNUNET_TIME_Absolute start_time;
static struct GNUNET_TIME_Absolute end_time;
static struct GNUNET_TIME_Relative total_time;
/**
* Check whether peers successfully shut down.
*/
static void
shutdown_callback (void *cls, const char *emsg)
{
if (emsg != NULL)
{
#if VERBOSE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Shutdown of peers failed!\n");
#endif
ok--;
}
else
{
#if VERBOSE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"All peers successfully shut down!\n");
#endif
}
GNUNET_CONFIGURATION_destroy (testing_cfg);
}
/**
* Shut down peergroup, clean up.
*/
static void
shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
#if VERBOSE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Ending test.\n");
#endif
if (disconnect_task != GNUNET_SCHEDULER_NO_TASK)
{
GNUNET_SCHEDULER_cancel (disconnect_task);
disconnect_task = GNUNET_SCHEDULER_NO_TASK;
}
if (NULL != h1)
{
GNUNET_MESH_disconnect (h1);
h1 = NULL;
}
if (NULL != h2)
{
GNUNET_MESH_disconnect (h2);
h2 = NULL;
}
if (test == MULTICAST && NULL != h3)
{
GNUNET_MESH_disconnect (h3);
h3 = NULL;
}
if (data_file != NULL)
GNUNET_DISK_file_close (data_file);
GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL);
}
/**
* Disconnect from mesh services af all peers, call shutdown.
*/
static void
disconnect_mesh_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"disconnecting mesh service of peers\n");
disconnect_task = GNUNET_SCHEDULER_NO_TASK;
if (NULL != t)
{
GNUNET_MESH_tunnel_destroy(t);
t = NULL;
}
if (NULL != incoming_t)
{
GNUNET_MESH_tunnel_destr