libgnunettransporttesting_la_SOURCES = \
transport-testing.c transport-testing.h \
transport-testing-filenames.c \
+ transport-testing-loggers.c \
transport-testing-main.c
libgnunettransporttesting_la_LIBADD = \
libgnunettransport.la \
/*
This file is part of GNUnet.
- Copyright (C) 2009, 2010, 2011 GNUnet e.V.
+ Copyright (C) 2009, 2010, 2011, 2016 GNUnet e.V.
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
#define DURATION GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
-static char *test_source;
-static char *test_plugin;
-
-static char *test_name;
-
-static struct GNUNET_SCHEDULER_Task * die_task;
-
-static struct GNUNET_SCHEDULER_Task * measure_task;
-
-struct GNUNET_TRANSPORT_TESTING_PeerContext *p1;
-
-struct GNUNET_TRANSPORT_TESTING_PeerContext *p2;
-
-struct GNUNET_TRANSPORT_TESTING_PeerContext *sender;
-
-struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver;
+static struct GNUNET_SCHEDULER_Task *measure_task;
struct GNUNET_TRANSPORT_TransmitHandle *th;
-char *cfg_file_p1;
-char *gen_cfg_p2;
-unsigned long long quota_in_p1;
-unsigned long long quota_out_p1;
+static char *gen_cfgs[2];
-char *cfg_file_p2;
-char *gen_cfg_p1;
-unsigned long long quota_in_p2;
-unsigned long long quota_out_p2;
+static unsigned long long quota_in[] = { 10000, 10000 };
-struct GNUNET_TRANSPORT_TESTING_Handle *tth;
+static unsigned long long quota_out[] = { 10000, 10000 };
-static struct GNUNET_TRANSPORT_TESTING_ConnectRequest * cc;
+static struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc;
/*
static int msg_scheduled;
static int msg_sent;
-static int test_failed;
-static int test_connected;
-
static unsigned long long total_bytes_sent;
static struct GNUNET_TIME_Absolute start_time;
static void
-end ()
+report ()
{
unsigned long long delta;
unsigned long long datarate;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping peers\n");
-
delta = GNUNET_TIME_absolute_get_duration (start_time).rel_value_us;
datarate = (total_bytes_sent * 1000 * 1000) / delta;
- FPRINTF (stderr, "Throughput was %llu b/s\n", datarate);
+ FPRINTF (stderr,
+ "Throughput was %llu b/s\n",
+ datarate);
- test_failed = GNUNET_NO;
- if (datarate > quota_in_p2)
+ if (datarate > quota_in[1])
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Datarate of %llu b/s higher than allowed inbound quota of %llu b/s\n",
- datarate, quota_in_p2);
- test_failed = GNUNET_YES;
+ datarate,
+ quota_in[1]);
+ ccc->global_ret = GNUNET_SYSERR;
}
- if (datarate > quota_out_p1)
+ if (datarate > quota_out[0])
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Datarate of %llu b/s higher than allowed outbound quota of %llu b/s\n",
- datarate, quota_out_p1);
- test_failed = GNUNET_YES;
+ datarate,
+ quota_out[0]);
+ ccc->global_ret = GNUNET_SYSERR;
}
- if (test_failed == GNUNET_NO)
+ if (GNUNET_OK == ccc->global_ret)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Datarate of %llu b/s complied to allowed outbound quota of %llu b/s and inbound quota of %llu b/s\n",
- datarate, quota_out_p1, quota_in_p2);
+ datarate,
+ quota_out[0],
+ quota_in[1]);
}
-
- if (die_task != NULL)
- GNUNET_SCHEDULER_cancel (die_task);
-
- if (th != NULL)
- GNUNET_TRANSPORT_notify_transmit_ready_cancel (th);
- th = NULL;
-
- if (cc != NULL)
- GNUNET_TRANSPORT_TESTING_connect_peers_cancel (cc);
-
- GNUNET_TRANSPORT_TESTING_stop_peer (p1);
- GNUNET_TRANSPORT_TESTING_stop_peer (p2);
-
}
+
static void
-end_badly ()
+custom_shutdown (void *cls)
{
- die_task = NULL;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Fail! Stopping peers\n");
-
- if (measure_task != NULL)
+ if (NULL != measure_task)
+ {
GNUNET_SCHEDULER_cancel (measure_task);
-
- if (test_connected == GNUNET_YES)
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Peers got connected\n");
- else
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Peers got NOT connected\n");
-
- if (th != NULL)
+ measure_task = NULL;
+ }
+ if (NULL != th)
+ {
GNUNET_TRANSPORT_notify_transmit_ready_cancel (th);
- th = NULL;
-
- if (cc != NULL)
- GNUNET_TRANSPORT_TESTING_connect_peers_cancel (cc);
-
- if (p1 != NULL)
- GNUNET_TRANSPORT_TESTING_stop_peer (p1);
- if (p2 != NULL)
- GNUNET_TRANSPORT_TESTING_stop_peer (p2);
-
- test_failed = GNUNET_YES;
+ th = NULL;
+ }
+ report ();
}
static void
notify_receive (void *cls,
- const struct GNUNET_PeerIdentity *peer,
+ struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver,
+ const struct GNUNET_PeerIdentity *sender,
const struct GNUNET_MessageHeader *message)
{
const struct TestMessage *hdr;
- struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls;
hdr = (const struct TestMessage *) message;
if (MTYPE != ntohs (message->type))
return;
{
- char *ps = GNUNET_strdup (GNUNET_i2s (&p->id));
+ char *ps = GNUNET_strdup (GNUNET_i2s (&receiver->id));
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Peer %u (`%s') got message %u of size %u from peer (`%s')\n",
- p->no,
+ receiver->no,
ps,
ntohl (hdr->num),
ntohs (message->size),
- GNUNET_i2s (peer));
+ GNUNET_i2s (sender));
GNUNET_free (ps);
}
}
static size_t
-notify_ready (void *cls, size_t size, void *buf)
+notify_ready (void *cls,
+ size_t size,
+ void *buf)
{
static int n;
char *cbuf = buf;
unsigned int ret;
th = NULL;
- if (buf == NULL)
+ if (NULL == buf)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Timeout occurred while waiting for transmit_ready for message %u of %u\n",
msg_scheduled, TOTAL_MSGS);
- if (NULL != die_task)
- GNUNET_SCHEDULER_cancel (die_task);
- die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL);
- test_failed = 1;
+ GNUNET_SCHEDULER_shutdown ();
+ ccc->global_ret = GNUNET_SYSERR;
return 0;
}
if (n % 5000 == 0)
{
#endif
- char *receiver_s = GNUNET_strdup (GNUNET_i2s (&receiver->id));
+ char *receiver_s = GNUNET_strdup (GNUNET_i2s (&ccc->p[0]->id));
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Sending message %u of size %u from peer %u (`%4s') -> peer %u (`%s') !\n",
- n, s, sender->no, GNUNET_i2s (&sender->id), receiver->no,
+ n, s,
+ ccc->p[1]->no,
+ GNUNET_i2s (&ccc->p[1]->id),
+ ccc->p[0]->no,
receiver_s);
GNUNET_free (receiver_s);
#if 0
if (n < TOTAL_MSGS)
{
if (th == NULL)
- th = GNUNET_TRANSPORT_notify_transmit_ready (p2->th, &p1->id, s,
+ th = GNUNET_TRANSPORT_notify_transmit_ready (ccc->p[1]->th,
+ &ccc->p[0]->id,
+ s,
TIMEOUT_TRANSMIT,
- ¬ify_ready, NULL);
+ ¬ify_ready,
+ NULL);
msg_scheduled = n;
}
if (n % 5000 == 0)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Returning total message block of size %u\n", ret);
+ "Returning total message block of size %u\n",
+ ret);
}
total_bytes_sent += ret;
if (n == TOTAL_MSGS)
{
FPRINTF (stderr, "%s", "\n");
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All messages sent\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "All messages sent\n");
}
return ret;
}
static void
-notify_connect (void *cls, const struct GNUNET_PeerIdentity *peer)
-{
-
- struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Peer %u (`%4s') connected to us!\n",
- p->no,
- GNUNET_i2s (peer));
-}
-
-
-static void
-notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
+notify_disconnect (void *cls,
+ struct GNUNET_TRANSPORT_TESTING_PeerContext *me,
+ const struct GNUNET_PeerIdentity *other)
{
- struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Peer %u (`%4s') disconnected!\n",
- p->no,
- GNUNET_i2s (peer));
+ GNUNET_TRANSPORT_TESTING_log_disconnect (cls,
+ me,
+ other);
if (th != NULL)
+ {
GNUNET_TRANSPORT_notify_transmit_ready_cancel (th);
- th = NULL;
-
+ th = NULL;
+ }
}
+
static void
sendtask ()
{
start_time = GNUNET_TIME_absolute_get ();
- th = GNUNET_TRANSPORT_notify_transmit_ready (p2->th, &p1->id, get_size (0),
- TIMEOUT_TRANSMIT, ¬ify_ready,
+ th = GNUNET_TRANSPORT_notify_transmit_ready (ccc->p[1]->th,
+ &ccc->p[0]->id,
+ get_size (0),
+ TIMEOUT_TRANSMIT,
+ ¬ify_ready,
NULL);
}
static int counter;
measure_task = NULL;
-
counter++;
if ((DURATION.rel_value_us / 1000 / 1000LL) < counter)
{
FPRINTF (stderr, "%s", ".\n");
- GNUNET_SCHEDULER_add_now (&end, NULL);
- }
- else
- {
- FPRINTF (stderr, "%s", ".");
- measure_task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &measure, NULL);
+ GNUNET_SCHEDULER_shutdown ();
+ return;
}
+ FPRINTF (stderr, "%s", ".");
+ measure_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
+ &measure,
+ NULL);
}
static void
-testing_connect_cb (void *cls)
-{
- char *p1_c = GNUNET_strdup (GNUNET_i2s (&p1->id));
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peers connected: %u (%s) <-> %u (%s)\n",
- p1->no, p1_c, p2->no, GNUNET_i2s (&p2->id));
- GNUNET_free (p1_c);
-
- cc = NULL;
- test_connected = GNUNET_YES;
-
- measure_task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &measure, NULL);
- GNUNET_SCHEDULER_add_now (&sendtask, NULL);
-
-}
-
-
-static void
-start_cb (struct GNUNET_TRANSPORT_TESTING_PeerContext *p, void *cls)
+start_task (void *cls)
{
- static int started;
-
- started++;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer %u (`%s') started\n", p->no,
- GNUNET_i2s (&p->id));
-
- if (started != 2)
- return;
-
- test_connected = GNUNET_NO;
-
- sender = p2;
- receiver = p1;
-
- char *sender_c = GNUNET_strdup (GNUNET_i2s (&sender->id));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Test tries to send from %u (%s) -> peer %u (%s)\n", sender->no,
- sender_c, receiver->no, GNUNET_i2s (&receiver->id));
- GNUNET_free (sender_c);
- cc = GNUNET_TRANSPORT_TESTING_connect_peers (p1, p2, &testing_connect_cb,
+ measure_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
+ &measure,
NULL);
-
+ GNUNET_SCHEDULER_add_now (&sendtask,
+ NULL);
}
+
static char *
-generate_config (char *cfg_file, unsigned long long quota_in,
+generate_config (const char *cfg_file,
+ unsigned long long quota_in,
unsigned long long quota_out)
{
char *in_name;
char *out_name;
char *fname = NULL;
struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create ();
- int c;
- GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (cfg, cfg_file));
- GNUNET_asprintf (&fname, "q_in_%llu_q_out_%llu_%s", quota_in, quota_out,
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CONFIGURATION_load (cfg,
+ cfg_file));
+ GNUNET_asprintf (&fname,
+ "q_in_%llu_q_out_%llu_%s",
+ quota_in,
+ quota_out,
cfg_file);
-
- GNUNET_CONFIGURATION_set_value_string (cfg, "PATHS", "DEFAULTCONFIG", fname);
-
- for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c++)
+ GNUNET_CONFIGURATION_set_value_string (cfg,
+ "PATHS",
+ "DEFAULTCONFIG",
+ fname);
+ for (int c = 0; c < GNUNET_ATS_NetworkTypeCount; c++)
{
GNUNET_asprintf (&in_name,
"%s_QUOTA_IN",
GNUNET_asprintf (&out_name,
"%s_QUOTA_OUT",
GNUNET_ATS_print_network_type (c));
- GNUNET_CONFIGURATION_set_value_number (cfg, "ats", in_name, quota_in);
- GNUNET_CONFIGURATION_set_value_number (cfg, "ats", out_name, quota_out);
+ GNUNET_CONFIGURATION_set_value_number (cfg,
+ "ats",
+ in_name,
+ quota_in);
+ GNUNET_CONFIGURATION_set_value_number (cfg,
+ "ats",
+ out_name,
+ quota_out);
GNUNET_free (in_name);
GNUNET_free (out_name);
}
- GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_write (cfg, fname));
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CONFIGURATION_write (cfg,
+ fname));
GNUNET_CONFIGURATION_destroy (cfg);
return fname;
}
-static void
-run_measurement (unsigned long long p1_quota_in,
- unsigned long long p1_quota_out,
- unsigned long long p2_quota_in,
- unsigned long long p2_quota_out)
-{
- die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
-
- /* setting ATS quota */
- quota_out_p1 = p1_quota_out;
- gen_cfg_p1 = generate_config (cfg_file_p1, p1_quota_in, p1_quota_out);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Generated config file `%s'\n",
- gen_cfg_p1);
-
- quota_in_p2 = p2_quota_in;
- gen_cfg_p2 = generate_config (cfg_file_p2, p2_quota_in, p2_quota_out);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Generated config file `%s'\n",
- gen_cfg_p2);
-
- p1 = GNUNET_TRANSPORT_TESTING_start_peer (tth, gen_cfg_p1, 1, ¬ify_receive,
- ¬ify_connect, ¬ify_disconnect,
- &start_cb, NULL);
-
- p2 = GNUNET_TRANSPORT_TESTING_start_peer (tth, gen_cfg_p2, 2, ¬ify_receive,
- ¬ify_connect, ¬ify_disconnect,
- &start_cb, NULL);
-
- if ((p1 == NULL) || (p2 == NULL))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Fail! Could not start peers!\n");
- if (die_task != NULL)
- GNUNET_SCHEDULER_cancel (die_task);
- die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL);
- return;
- }
-}
-
-static void
-run (void *cls, char *const *args, const char *cfgfile,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
+static int
+check (void *cls,
+ struct GNUNET_TRANSPORT_TESTING_Handle *tth_,
+ const char *test_plugin_,
+ const char *test_name_,
+ unsigned int num_peers,
+ char *cfg_files[])
{
- unsigned long long p1_quota_in = 10000;
- unsigned long long p1_quota_out = 10000;
- unsigned long long p2_quota_in = 10000;
- unsigned long long p2_quota_out = 10000;
+ struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext my_ccc = {
+ .connect_continuation = &start_task,
+ .config_file = "test_quota_compliance_data.conf",
+ .rec = ¬ify_receive,
+ .nc = &GNUNET_TRANSPORT_TESTING_log_connect,
+ .nd = ¬ify_disconnect,
+ .shutdown_task = &custom_shutdown,
+ .timeout = TIMEOUT
+ };
+ ccc = &my_ccc;
- if (NULL != strstr (test_name, "asymmetric"))
+ if (NULL != strstr (test_name_,
+ "asymmetric"))
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Running asymmetric test with sending peer unlimited, receiving peer (in/out): %llu/%llu b/s \n",
- p2_quota_in, p2_quota_out);
- p1_quota_out = 1024 * 1024 * 1024;
- p1_quota_in = 1024 * 1024 * 1024;
+ quota_in[1],
+ quota_out[1]);
+ quota_out[0] = 1024 * 1024 * 1024;
+ quota_in[0] = 1024 * 1024 * 1024;
}
else
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Running symmetric test with (in/out) %llu/%llu b/s \n",
- p2_quota_in, p2_quota_out);
+ quota_in[1],
+ quota_out[1]);
+ }
+ for (unsigned int i=0;i<2;i++)
+ {
+ gen_cfgs[i] = generate_config (cfg_files[i],
+ quota_in[i],
+ quota_out[i]);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Generated config file `%s'\n",
+ gen_cfgs[i]);
}
- run_measurement (p1_quota_in, p1_quota_out, p2_quota_in, p2_quota_out);
-}
-
-static int
-check ()
-{
- static char *argv[] = { "test_transport-quota-compliance",
- "-c",
- "test_quota_compliance_data.conf",
- NULL
- };
- static struct GNUNET_GETOPT_CommandLineOption options[] = {
- GNUNET_GETOPT_OPTION_END
- };
- GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, test_name,
- "nohelp", options, &run, NULL);
- return test_failed;
+ return GNUNET_TRANSPORT_TESTING_connect_check (&my_ccc,
+ tth_,
+ test_plugin_,
+ test_name_,
+ num_peers,
+ gen_cfgs);
}
+
int
main (int argc, char *argv[])
{
- test_name = GNUNET_TRANSPORT_TESTING_get_test_name (argv[0]);
-
- GNUNET_log_setup (test_name,
- "WARNING",
- NULL);
-
- test_source = GNUNET_TRANSPORT_TESTING_get_test_source_name (__FILE__);
- test_plugin = GNUNET_TRANSPORT_TESTING_get_test_plugin_name (argv[0], test_source);
-
- tth = GNUNET_TRANSPORT_TESTING_init ();
-
- cfg_file_p1 = GNUNET_TRANSPORT_TESTING_get_config_name (argv[0], 1);
- cfg_file_p2 = GNUNET_TRANSPORT_TESTING_get_config_name (argv[0], 2);
-
- check ();
-
- GNUNET_free (cfg_file_p1);
- GNUNET_free (cfg_file_p2);
-
- if (GNUNET_YES == GNUNET_DISK_file_test (gen_cfg_p1))
+ if (GNUNET_OK !=
+ GNUNET_TRANSPORT_TESTING_main (2,
+ &check,
+ NULL))
{
- GNUNET_DISK_directory_remove (gen_cfg_p1);
- GNUNET_free (gen_cfg_p1);
+ GNUNET_break (0);
+ return 1;
}
-
- if (GNUNET_YES == GNUNET_DISK_file_test (gen_cfg_p2))
+ for (unsigned int i=0;i<2;i++)
{
- GNUNET_DISK_directory_remove (gen_cfg_p2);
- GNUNET_free (gen_cfg_p2);
+ if ( (NULL != gen_cfgs[0]) &&
+ (GNUNET_YES == GNUNET_DISK_file_test (gen_cfgs[0])) )
+ {
+ GNUNET_DISK_directory_remove (gen_cfgs[0]);
+ GNUNET_free (gen_cfgs[0]);
+ }
}
-
- GNUNET_free (test_source);
- GNUNET_free (test_plugin);
- GNUNET_free (test_name);
-
- GNUNET_TRANSPORT_TESTING_done (tth);
-
- return test_failed;
+ return 0;
}
/*
This file is part of GNUnet.
- Copyright (C) 2009, 2010 GNUnet e.V.
+ Copyright (C) 2009, 2010, 2016 GNUnet e.V.
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
#define TEST_MESSAGE_TYPE 12345
-static char *test_source;
-static char *test_plugin;
-
-static char *test_name;
-
-static int ok;
-
-static int s_started;
-
-static int s_connected;
-
-static int s_sending;
-
-static struct GNUNET_SCHEDULER_Task * die_task;
-
-static struct GNUNET_SCHEDULER_Task * send_task;
-
-static struct GNUNET_TRANSPORT_TESTING_PeerContext *p1;
-
-static struct GNUNET_TRANSPORT_TESTING_PeerContext *p2;
-
-static struct GNUNET_TRANSPORT_TESTING_ConnectRequest * cc;
+static struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc;
static struct GNUNET_TRANSPORT_TransmitHandle *th;
-static struct GNUNET_TRANSPORT_TESTING_Handle *tth;
-
-static char *cfg_file_p1;
-
-static char *cfg_file_p2;
-
-
-static void
-end ()
-{
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stopping peers\n");
-
- if (send_task != NULL)
- GNUNET_SCHEDULER_cancel (send_task);
-
- if (die_task != NULL)
- GNUNET_SCHEDULER_cancel (die_task);
-
- if (th != NULL)
- GNUNET_TRANSPORT_notify_transmit_ready_cancel (th);
- th = NULL;
-
- GNUNET_TRANSPORT_TESTING_stop_peer (p1);
- GNUNET_TRANSPORT_TESTING_stop_peer (p2);
-}
-
static void
-end_badly (void *cls)
+custom_shutdown (void *cls)
{
- die_task = NULL;
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Fail! Stopping peers\n");
-
-
- if (send_task != NULL)
- GNUNET_SCHEDULER_cancel (send_task);
-
- if (cc != NULL)
+ if (NULL != th)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Fail! Could not connect peers\n"));
- GNUNET_TRANSPORT_TESTING_connect_peers_cancel (cc);
- cc = NULL;
- }
-
- if (th != NULL)
GNUNET_TRANSPORT_notify_transmit_ready_cancel (th);
+ th = NULL;
+ }
else
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer were not ready to send data\n"));
-
- if (s_started == GNUNET_NO)
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peers were not started \n"));
- else
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peers were started \n"));
-
- if (s_connected == GNUNET_NO)
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer were not connected\n"));
- else
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer were connected\n"));
-
- if (s_sending == GNUNET_NO)
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer were not ready to send data\n"));
- else
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer were ready to send data\n"));
-
- th = NULL;
-
- if (p1 != NULL)
- GNUNET_TRANSPORT_TESTING_stop_peer (p1);
- else
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer 1 was not started\n"));
- if (p2 != NULL)
- GNUNET_TRANSPORT_TESTING_stop_peer (p2);
- else
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer 2 was not started\n"));
-
- ok = GNUNET_SYSERR;
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Peers were not ready to send data\n");
}
static void
-notify_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
+notify_receive (void *cls,
+ struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver,
+ const struct GNUNET_PeerIdentity *sender,
const struct GNUNET_MessageHeader *message)
{
- struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls;
- struct GNUNET_TRANSPORT_TESTING_PeerContext *t = NULL;
-
- if (0 == memcmp (peer, &p1->id, sizeof (struct GNUNET_PeerIdentity)))
- t = p1;
- if (0 == memcmp (peer, &p2->id, sizeof (struct GNUNET_PeerIdentity)))
- t = p2;
- GNUNET_assert (t != NULL);
-
- char *ps = GNUNET_strdup (GNUNET_i2s (&p->id));
+ {
+ char *ps = GNUNET_strdup (GNUNET_i2s (&receiver->id));
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Peer %u (`%4s') received message of type %d and size %u size from peer %u (`%4s')!\n",
- p->no, ps, ntohs (message->type), ntohs (message->size), t->no,
- GNUNET_i2s (&t->id));
- GNUNET_free (ps);
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Peer %u (`%4s') received message of type %d and size %u size from peer %s!\n",
+ receiver->no,
+ ps,
+ ntohs (message->type),
+ ntohs (message->size),
+ GNUNET_i2s (sender));
+ GNUNET_free (ps);
+ }
if ((TEST_MESSAGE_TYPE == ntohs (message->type)) &&
(TEST_MESSAGE_SIZE == ntohs (message->size)))
{
- ok = 0;
- end ();
+ ccc->global_ret = GNUNET_OK;
+ GNUNET_SCHEDULER_shutdown ();
}
else
{
GNUNET_break (0);
- ok = 1;
- end ();
+ ccc->global_ret = GNUNET_SYSERR;
+ GNUNET_SCHEDULER_shutdown ();
}
}
static size_t
-notify_ready (void *cls, size_t size, void *buf)
+notify_ready (void *cls,
+ size_t size,
+ void *buf)
{
struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls;
struct GNUNET_MessageHeader *hdr;
th = NULL;
-
if (buf == NULL)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Timeout occurred while waiting for transmit_ready\n");
- if (NULL != die_task)
- GNUNET_SCHEDULER_cancel (die_task);
- die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL);
- ok = 42;
+ GNUNET_SCHEDULER_shutdown ();
+ ccc->global_ret = 42;
return 0;
}
GNUNET_assert (size >= TEST_MESSAGE_SIZE);
- if (buf != NULL)
+ if (NULL != buf)
{
memset (buf, '\0', TEST_MESSAGE_SIZE);
hdr = buf;
hdr->type = htons (TEST_MESSAGE_TYPE);
}
- char *ps = GNUNET_strdup (GNUNET_i2s (&p2->id));
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Peer %u (`%4s') sending message with type %u and size %u bytes to peer %u (`%4s')\n",
- p2->no, ps, ntohs (hdr->type), ntohs (hdr->size), p->no,
- GNUNET_i2s (&p->id));
- GNUNET_free (ps);
-
- return TEST_MESSAGE_SIZE;
-}
-
-
-static void
-sendtask (void *cls)
-{
- send_task = NULL;
- char *receiver_s = GNUNET_strdup (GNUNET_i2s (&p1->id));
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Sending message from peer %u (`%4s') -> peer %u (`%s') !\n",
- p2->no, GNUNET_i2s (&p2->id), p1->no, receiver_s);
- GNUNET_free (receiver_s);
- s_sending = GNUNET_YES;
- th = GNUNET_TRANSPORT_notify_transmit_ready (p2->th, &p1->id, TEST_MESSAGE_SIZE,
- TIMEOUT_TRANSMIT, ¬ify_ready,
- p1);
-}
-
-
-static void
-notify_connect (void *cls,
- const struct GNUNET_PeerIdentity *peer)
-{
- static int c;
-
- c++;
- struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls;
- struct GNUNET_TRANSPORT_TESTING_PeerContext *t = NULL;
-
- if (0 == memcmp (peer, &p1->id, sizeof (struct GNUNET_PeerIdentity)))
- t = p1;
- if (0 == memcmp (peer, &p2->id, sizeof (struct GNUNET_PeerIdentity)))
- t = p2;
- GNUNET_assert (t != NULL);
-
- char *ps = GNUNET_strdup (GNUNET_i2s (&p->id));
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Peer %u (`%4s'): peer %u (`%s') connected to me!\n", p->no, ps,
- t->no, GNUNET_i2s (peer));
- GNUNET_free (ps);
-}
-
-
-static void
-notify_disconnect (void *cls,
- const struct GNUNET_PeerIdentity *peer)
-{
- struct GNUNET_TRANSPORT_TESTING_PeerContext *p = cls;
- char *ps = GNUNET_strdup (GNUNET_i2s (&p->id));
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Peer %u (`%4s'): peer (`%s') disconnected from me!\n",
- p->no,
- ps,
- GNUNET_i2s (peer));
- GNUNET_free (ps);
-
- if (th != NULL)
{
- GNUNET_TRANSPORT_notify_transmit_ready_cancel (th);
- th = NULL;
+ char *ps = GNUNET_strdup (GNUNET_i2s (&ccc->p[1]->id));
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Peer %u (`%4s') sending message with type %u and size %u bytes to peer %u (`%4s')\n",
+ ccc->p[1]->no,
+ ps,
+ ntohs (hdr->type),
+ ntohs (hdr->size),
+ p->no,
+ GNUNET_i2s (&p->id));
+ GNUNET_free (ps);
}
+ return TEST_MESSAGE_SIZE;
}
static void
-testing_connect_cb (void *cls)
-{
- cc = NULL;
- char *p1_c = GNUNET_strdup (GNUNET_i2s (&p1->id));
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Peers connected: %u (%s) <-> %u (%s)\n",
- p1->no, p1_c, p2->no, GNUNET_i2s (&p2->id));
- GNUNET_free (p1_c);
-
- s_connected = GNUNET_YES;
- send_task = GNUNET_SCHEDULER_add_now (&sendtask, NULL);
-}
-
-
-static void
-start_cb (struct GNUNET_TRANSPORT_TESTING_PeerContext *p,
- void *cls)
+sendtask (void *cls)
{
- static int started;
-
- started++;
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Peer %u (`%s') started\n",
- p->no,
- GNUNET_i2s (&p->id));
- if (started != 2)
- return;
- s_started = GNUNET_YES;
{
- char *sender_c = GNUNET_strdup (GNUNET_i2s (&p1->id));
+ char *receiver_s = GNUNET_strdup (GNUNET_i2s (&ccc->p[0]->id));
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Test tries to connect peer %u (`%s') -> peer %u (`%s')\n",
- p1->no, sender_c, p2->no, GNUNET_i2s (&p2->id));
- GNUNET_free (sender_c);
+ "Sending message from peer %u (`%4s') -> peer %u (`%s') !\n",
+ ccc->p[1]->no,
+ GNUNET_i2s (&ccc->p[1]->id),
+ ccc->p[0]->no,
+ receiver_s);
+ GNUNET_free (receiver_s);
}
- cc = GNUNET_TRANSPORT_TESTING_connect_peers (p1,
- p2,
- &testing_connect_cb,
- NULL);
+ ccc->global_ret = GNUNET_SYSERR;
+ th = GNUNET_TRANSPORT_notify_transmit_ready (ccc->p[1]->th,
+ &ccc->p[0]->id,
+ TEST_MESSAGE_SIZE,
+ TIMEOUT_TRANSMIT,
+ ¬ify_ready,
+ ccc->p[0]);
}
static void
-run (void *cls,
- char *const *args,
- const char *cfgfile,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
+notify_disconnect (void *cls,
+ struct GNUNET_TRANSPORT_TESTING_PeerContext *me,
+ const struct GNUNET_PeerIdentity *other)
{
- die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
- &end_badly,
- NULL);
-
- s_started = GNUNET_NO;
- s_connected = GNUNET_NO;
- s_sending = GNUNET_NO;
-
- p1 = GNUNET_TRANSPORT_TESTING_start_peer (tth, cfg_file_p1, 1,
- ¬ify_receive, ¬ify_connect,
- ¬ify_disconnect, &start_cb,
- NULL);
-
- p2 = GNUNET_TRANSPORT_TESTING_start_peer (tth, cfg_file_p2, 2,
- ¬ify_receive, ¬ify_connect,
- ¬ify_disconnect, &start_cb,
- NULL);
-
- if ((p1 == NULL) || (p2 == NULL))
+ GNUNET_TRANSPORT_TESTING_log_disconnect (cls,
+ me,
+ other);
+ if (NULL != th)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Fail! Could not start peers!\n");
- if (die_task != NULL)
- GNUNET_SCHEDULER_cancel (die_task);
- die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL);
- return;
+ GNUNET_TRANSPORT_notify_transmit_ready_cancel (th);
+ th = NULL;
}
}
-static int
-check ()
-{
- static char *const argv[] = {
- "test-transport-api",
- "-c",
- "test_transport_api_data.conf",
- NULL
- };
- static struct GNUNET_GETOPT_CommandLineOption options[] = {
- GNUNET_GETOPT_OPTION_END
- };
-
- send_task = NULL;
-
- ok = 1;
- GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
- argv,
- test_name,
- "nohelp",
- options,
- &run,
- &ok);
-
- return ok;
-}
-
-
int
-main (int argc, char *argv[])
+main (int argc,
+ char *argv[])
{
- int ret;
-
- test_name = GNUNET_TRANSPORT_TESTING_get_test_name (argv[0]);
- test_source = GNUNET_TRANSPORT_TESTING_get_test_source_name (__FILE__);
- test_plugin = GNUNET_TRANSPORT_TESTING_get_test_plugin_name (argv[0],
- test_source);
-
- GNUNET_log_setup (test_name,
- "WARNING",
- NULL);
- tth = GNUNET_TRANSPORT_TESTING_init ();
-
- cfg_file_p1 = GNUNET_TRANSPORT_TESTING_get_config_name (argv[0],
- 1);
- cfg_file_p2 = GNUNET_TRANSPORT_TESTING_get_config_name (argv[0],
- 2);
-
- ret = check ();
-
- GNUNET_free (cfg_file_p1);
- GNUNET_free (cfg_file_p2);
-
- GNUNET_free (test_source);
- GNUNET_free (test_plugin);
- GNUNET_free (test_name);
-
- GNUNET_TRANSPORT_TESTING_done (tth);
+ struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext my_ccc = {
+ .connect_continuation = &sendtask,
+ .config_file = "test_transport_api_data.conf",
+ .rec = ¬ify_receive,
+ .nc = &GNUNET_TRANSPORT_TESTING_log_connect,
+ .nd = ¬ify_disconnect,
+ .shutdown_task = &custom_shutdown,
+ .timeout = TIMEOUT
+ };
- return ret;
+ ccc = &my_ccc;
+ if (GNUNET_OK !=
+ GNUNET_TRANSPORT_TESTING_main (2,
+ &GNUNET_TRANSPORT_TESTING_connect_check,
+ ccc))
+ return 1;
+ return 0;
}
/* end of test_transport_api.c */
--- /dev/null
+
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2016 GNUnet e.V.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ * @file transport-testing-loggers.c
+ * @brief convenience functions for logging common events in tests
+ * @author Christian Grothoff
+ */
+#include "transport-testing.h"
+
+
+/**
+ * Log a connect event.
+ *
+ * @param cls NULL
+ * @param me peer that had the event
+ * @param other peer that connected.
+ */
+void
+GNUNET_TRANSPORT_TESTING_log_connect (void *cls,
+ struct GNUNET_TRANSPORT_TESTING_PeerContext *me,
+ const struct GNUNET_PeerIdentity *other)
+{
+ char *ps;
+
+ ps = GNUNET_strdup (GNUNET_i2s (&me->id));
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Peer %s connected to %u (%s)!\n",
+ GNUNET_i2s (other),
+ me->no,
+ ps);
+ GNUNET_free (ps);
+}
+
+
+
+/**
+ * Log a disconnect event.
+ *
+ * @param cls NULL
+ * @param me peer that had the event
+ * @param other peer that disconnected.
+ */
+void
+GNUNET_TRANSPORT_TESTING_log_disconnect (void *cls,
+ struct GNUNET_TRANSPORT_TESTING_PeerContext *me,
+ const struct GNUNET_PeerIdentity *other)
+{
+ char *ps;
+
+ ps = GNUNET_strdup (GNUNET_i2s (&me->id));
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Peer `%s' disconnected from %u (%s)!\n",
+ GNUNET_i2s (other),
+ me->no,
+ ps);
+}
+
+/* end of transport-testing-loggers.c */
#include "transport-testing.h"
+/**
+ * Closure for #connect_cb.
+ */
+struct GNUNET_TRANSPORT_TESTING_ConnectRequestList
+{
+ /**
+ * Stored in a DLL.
+ */
+ struct GNUNET_TRANSPORT_TESTING_ConnectRequestList *next;
+
+ /**
+ * Stored in a DLL.
+ */
+ struct GNUNET_TRANSPORT_TESTING_ConnectRequestList *prev;
+
+ /**
+ * Overall context we are in.
+ */
+ struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc;
+
+ /**
+ * Connect request this is about.
+ */
+ struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cr;
+
+ /**
+ * Peer being connected.
+ */
+ struct GNUNET_TRANSPORT_TESTING_PeerContext *p1;
+
+ /**
+ * Peer being connected.
+ */
+ struct GNUNET_TRANSPORT_TESTING_PeerContext *p2;
+
+};
+
+
+/**
+ * Shutdown function for the test. Stops all peers.
+ *
+ * @param cls our `struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *`
+ */
+static void
+do_shutdown (void *cls)
+{
+ struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = cls;
+ struct GNUNET_TRANSPORT_TESTING_ConnectRequestList *crl;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Testcase shutting down\n");
+ if (NULL != ccc->shutdown_task)
+ ccc->shutdown_task (ccc->shutdown_task_cls);
+ if (NULL != ccc->timeout_task)
+ {
+ GNUNET_SCHEDULER_cancel (ccc->timeout_task);
+ ccc->timeout_task = NULL;
+ }
+ while (NULL != (crl = ccc->crl_head))
+ {
+ GNUNET_CONTAINER_DLL_remove (ccc->crl_head,
+ ccc->crl_tail,
+ crl);
+ GNUNET_TRANSPORT_TESTING_connect_peers_cancel (crl->cr);
+ GNUNET_free (crl);
+ }
+ for (unsigned int i=0;i<ccc->num_peers;i++)
+ {
+ GNUNET_TRANSPORT_TESTING_stop_peer (ccc->p[i]);
+ ccc->p[i] = NULL;
+ }
+}
+
+
+/**
+ * Testcase hit timeout, shut it down with error.
+ *
+ * @param cls our `struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *`
+ */
+static void
+do_timeout (void *cls)
+{
+ struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = cls;
+
+ ccc->timeout_task = NULL;
+ GNUNET_break (0); /* signal timeout */
+ ccc->global_ret = GNUNET_SYSERR;
+ GNUNET_SCHEDULER_shutdown ();
+}
+
+
+/**
+ * Internal data structure. Closure for
+ * #connect_cb, #disconnect_cb, #my_nc and #start_cb.
+ * Allows us to identify which peer this is about.
+ */
+struct GNUNET_TRANSPORT_TESTING_InternalPeerContext
+{
+ /**
+ * Overall context of the callback.
+ */
+ struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc;
+
+ /**
+ * Offset of the peer this is about.
+ */
+ unsigned int off;
+};
+
+
+/**
+ * Function called when we connected two peers.
+ * Once we have gotten to the clique, launch
+ * test-specific logic.
+ *
+ * @param cls our `struct GNUNET_TRANSPORT_TESTING_ConnectRequestList *`
+ */
+static void
+connect_cb (void *cls)
+{
+ struct GNUNET_TRANSPORT_TESTING_ConnectRequestList *crl = cls;
+ struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = crl->ccc;
+
+ GNUNET_CONTAINER_DLL_remove (ccc->crl_head,
+ ccc->crl_tail,
+ crl);
+ {
+ char *p1_c = GNUNET_strdup (GNUNET_i2s (&crl->p1->id));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Peers connected: %u (%s) <-> %u (%s)\n",
+ crl->p1->no,
+ p1_c,
+ crl->p2->no,
+ GNUNET_i2s (&crl->p2->id));
+ GNUNET_free (p1_c);
+ GNUNET_free (crl);
+ }
+ if (NULL == ccc->crl_head)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "All connections UP, launching custom test logic.\n");
+ GNUNET_SCHEDULER_add_now (ccc->connect_continuation,
+ ccc->connect_continuation_cls);
+ }
+}
+
+
+/**
+ * Find peer by peer ID.
+ *
+ * @param ccc context to search
+ * @param peer peer to look for
+ * @return NULL if @a peer was not found
+ */
+struct GNUNET_TRANSPORT_TESTING_PeerContext *
+GNUNET_TRANSPORT_TESTING_find_peer (struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc,
+ const struct GNUNET_PeerIdentity *peer)
+{
+ for (unsigned int i=0;i<ccc->num_peers;i++)
+ if ( (NULL != ccc->p[i]) &&
+ (0 == memcmp (peer,
+ &ccc->p[i]->id,
+ sizeof (*peer))) )
+ return ccc->p[i];
+ return NULL;
+}
+
+
+/**
+ * Wrapper around peers connecting. Calls client's nc function.
+ *
+ * @param cls our `struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *`
+ * @param peer peer we got connected to
+ */
+static void
+my_nc (void *cls,
+ const struct GNUNET_PeerIdentity *peer)
+{
+ struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *ipi = cls;
+ struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = ipi->ccc;
+
+ if (NULL != ccc->nc)
+ ccc->nc (ccc->cls,
+ ccc->p[ipi->off],
+ peer);
+}
+
+
+
+/**
+ * Wrapper around peers disconnecting. Calls client's nd function.
+ *
+ * @param cls our `struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *`
+ * @param peer peer we got disconnected from
+ */
+static void
+my_nd (void *cls,
+ const struct GNUNET_PeerIdentity *peer)
+{
+ struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *ipi = cls;
+ struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = ipi->ccc;
+
+ if (NULL != ccc->nd)
+ ccc->nd (ccc->cls,
+ ccc->p[ipi->off],
+ peer);
+}
+
+
+/**
+ * Wrapper around receiving data. Calls client's rec function.
+ *
+ * @param cls our `struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *`
+ * @param peer peer we got a message from
+ * @param message message we received
+ */
+static void
+my_rec (void *cls,
+ const struct GNUNET_PeerIdentity *peer,
+ const struct GNUNET_MessageHeader *message)
+{
+ struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *ipi = cls;
+ struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = ipi->ccc;
+
+ if (NULL != ccc->rec)
+ ccc->rec (ccc->cls,
+ ccc->p[ipi->off],
+ peer,
+ message);
+}
+
+
+/**
+ * Function called once we have successfully launched a peer.
+ * Once all peers have been launched, we connect all of them
+ * in a clique.
+ *
+ * @param p peer that was launched (redundant, kill ASAP)
+ * @param cls our `struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *`
+ */
+static void
+start_cb (struct GNUNET_TRANSPORT_TESTING_PeerContext *p,
+ void *cls)
+{
+ struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *ipi = cls;
+ struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = ipi->ccc;
+
+ ccc->started++;
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Peer %u (`%s') started\n",
+ p->no,
+ GNUNET_i2s (&p->id));
+ if (ccc->started != ccc->num_peers)
+ return;
+
+ for (unsigned int i=0;i<ccc->num_peers;i++)
+ for (unsigned int j=i+1;j<ccc->num_peers;j++)
+ {
+ struct GNUNET_TRANSPORT_TESTING_ConnectRequestList *crl;
+
+ crl = GNUNET_new (struct GNUNET_TRANSPORT_TESTING_ConnectRequestList);
+ GNUNET_CONTAINER_DLL_insert (ccc->crl_head,
+ ccc->crl_tail,
+ crl);
+ crl->ccc = ccc;
+ crl->p1 = ccc->p[i];
+ crl->p2 = ccc->p[j];
+ {
+ char *sender_c = GNUNET_strdup (GNUNET_i2s (&ccc->p[0]->id));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test tries to connect peer %u (`%s') -> peer %u (`%s')\n",
+ ccc->p[0]->no,
+ sender_c,
+ ccc->p[1]->no,
+ GNUNET_i2s (&ccc->p[1]->id));
+ GNUNET_free (sender_c);
+ }
+ crl->cr = GNUNET_TRANSPORT_TESTING_connect_peers (ccc->p[i],
+ ccc->p[j],
+ &connect_cb,
+ crl);
+ }
+}
+
+
+/**
+ * Function run from #GNUNET_TRANSPORT_TESTING_connect_check
+ * once the scheduler is up. Should launch the peers and
+ * then in the continuations try to connect them.
+ *
+ * @param cls our `struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *`
+ * @param args ignored
+ * @param cfgfile ignored
+ * @param cfg configuration
+ */
+static void
+connect_check_run (void *cls,
+ char *const *args,
+ const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = cls;
+ int ok;
+
+ ccc->cfg = cfg;
+ ccc->timeout_task = GNUNET_SCHEDULER_add_delayed (ccc->timeout,
+ &do_timeout,
+ ccc);
+ GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
+ ccc);
+ ok = GNUNET_OK;
+ for (unsigned int i=0;i<ccc->num_peers;i++)
+ {
+ ccc->p[i] = GNUNET_TRANSPORT_TESTING_start_peer (ccc->tth,
+ ccc->cfg_files[i],
+ i + 1,
+ &my_rec,
+ &my_nc,
+ &my_nd,
+ &start_cb,
+ &ccc->ip[i]);
+ if (NULL == ccc->p[i])
+ ok = GNUNET_SYSERR;
+ }
+ if (GNUNET_OK != ok)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Fail! Could not start peers!\n");
+ GNUNET_SCHEDULER_shutdown ();
+ }
+}
+
+
+/**
+ * Common implementation of the #GNUNET_TRANSPORT_TESTING_CheckCallback.
+ * Starts and connects the two peers, then invokes the
+ * `connect_continuation` from @a cls. Sets up a timeout to
+ * abort the test, and a shutdown handler to clean up properly
+ * on exit.
+ *
+ * @param cls closure of type `struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext`
+ * @param tth_ initialized testing handle
+ * @param test_plugin_ name of the plugin
+ * @param test_name_ name of the test
+ * @param num_peers number of entries in the @a cfg_file array
+ * @param cfg_files array of names of configuration files for the peers
+ * @return #GNUNET_SYSERR on error
+ */
+int
+GNUNET_TRANSPORT_TESTING_connect_check (void *cls,
+ struct GNUNET_TRANSPORT_TESTING_Handle *tth_,
+ const char *test_plugin_,
+ const char *test_name_,
+ unsigned int num_peers,
+ char *cfg_files[])
+{
+ static struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+ struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc = cls;
+ struct GNUNET_TRANSPORT_TESTING_PeerContext *p[num_peers];
+ struct GNUNET_TRANSPORT_TESTING_InternalPeerContext ip[num_peers];
+ char * argv[] = {
+ (char *) test_name_,
+ "-c",
+ (char *) ccc->config_file,
+ NULL
+ };
+
+ ccc->num_peers = num_peers;
+ ccc->cfg_files = cfg_files;
+ ccc->test_plugin = test_plugin_;
+ ccc->test_name = test_name_;
+ ccc->tth = tth_;
+ ccc->global_ret = GNUNET_OK;
+ ccc->p = p;
+ ccc->ip = ip;
+ for (unsigned int i=0;i<num_peers;i++)
+ {
+ ip[i].off = i;
+ ip[i].ccc = ccc;
+ }
+ GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
+ argv,
+ test_name_,
+ "nohelp",
+ options,
+ &connect_check_run,
+ ccc);
+ return ccc->global_ret;
+}
+
+
/**
* Setup testcase. Calls @a check with the data the test needs.
*
GNUNET_TRANSPORT_TESTING_CheckCallback check,
void *check_cls)
{
- return GNUNET_SYSERR;
+ struct GNUNET_TRANSPORT_TESTING_Handle *tth;
+ char *test_name;
+ char *test_source;
+ char *test_plugin;
+ char *cfg_names[num_peers];
+ int ret;
+
+ ret = GNUNET_OK;
+ test_name = GNUNET_TRANSPORT_TESTING_get_test_name (argv0);
+ GNUNET_log_setup (test_name,
+ "WARNING",
+ NULL);
+ test_source = GNUNET_TRANSPORT_TESTING_get_test_source_name (filename);
+ test_plugin = GNUNET_TRANSPORT_TESTING_get_test_plugin_name (argv0,
+ test_source);
+ for (unsigned int i=0;i<num_peers;i++)
+ cfg_names[i] = GNUNET_TRANSPORT_TESTING_get_config_name (argv0,
+ i+1);
+ tth = GNUNET_TRANSPORT_TESTING_init ();
+ if (NULL == tth)
+ {
+ ret = GNUNET_SYSERR;
+ }
+ else
+ {
+ ret = check (check_cls,
+ tth,
+ test_plugin,
+ test_name,
+ num_peers,
+ cfg_names);
+ GNUNET_TRANSPORT_TESTING_done (tth);
+ }
+ for (unsigned int i=0;i<num_peers;i++)
+ GNUNET_free (cfg_names[i]);
+ GNUNET_free (test_source);
+ GNUNET_free (test_plugin);
+ GNUNET_free (test_name);
+ return ret;
}
/* end of transport-testing-main.c */
#include "gnunet_testing_lib.h"
+/* ************* Basic functions for starting/stopping/connecting *********** */
+
/**
* Context for a single peer
*/
/**
* Callback when two peers are connected and both have called the connect callback
* to notify clients about a new peer
+ *
+ * @param p FIXME: remove ASAP.
+ * @param cls closure
*/
typedef void
(*GNUNET_TRANSPORT_TESTING_StartCallback) (struct GNUNET_TRANSPORT_TESTING_PeerContext *p,
void *cls);
+
/**
* Context for a single peer
*/
*/
struct GNUNET_TRANSPORT_TESTING_ConnectRequest
{
+ /**
+ * Kept in a DLL.
+ */
struct GNUNET_TRANSPORT_TESTING_ConnectRequest *next;
+
+ /**
+ * Kept in a DLL.
+ */
struct GNUNET_TRANSPORT_TESTING_ConnectRequest *prev;
+
+ /**
+ * Peer we want to connect.
+ */
struct GNUNET_TRANSPORT_TESTING_PeerContext *p1;
+
+ /**
+ * Peer we want to connect.
+ */
struct GNUNET_TRANSPORT_TESTING_PeerContext *p2;
+
+ /**
+ * Task by which we accomplish the connection.
+ */
struct GNUNET_SCHEDULER_Task *tct;
+
+ /**
+ * Handle by which we ask ATS to faciliate the connection.
+ */
struct GNUNET_ATS_ConnectivitySuggestHandle *ats_sh;
+
+ /**
+ * Handle by which we inform the peer about the HELLO of
+ * the other peer.
+ */
struct GNUNET_TRANSPORT_OfferHelloHandle *oh;
+
+ /**
+ * Function to call upon completion.
+ */
GNUNET_SCHEDULER_TaskCallback cb;
+
+ /**
+ * Closure for @e cb.
+ */
void *cb_cls;
- int p1_c;
- int p2_c;
+
+ int p1_c; // dead?
+ int p2_c; // dead?
};
void
GNUNET_TRANSPORT_TESTING_connect_peers_cancel (struct GNUNET_TRANSPORT_TESTING_ConnectRequest *cc);
+
/* ********************** high-level process functions *************** */
+/**
+ * Function called once the peers have been launched and
+ * connected by #GNUNET_TRANSPORT_TESTING_connect_check().
+ *
+ * @param cls closure
+ * @param num_peers size of the @a p array
+ * @param p the peers that were launched
+ */
+typedef void
+(*GNUNET_TRANSPORT_TESTING_ConnectContinuation)(void *cls,
+ unsigned int num_peers,
+ struct GNUNET_TRANSPORT_TESTING_PeerContext *p[]);
+
+
+/**
+ * Internal data structure.
+ */
+struct GNUNET_TRANSPORT_TESTING_ConnectRequestList;
+
+/**
+ * Internal data structure.
+ */
+struct GNUNET_TRANSPORT_TESTING_InternalPeerContext;
+
+
+/**
+ * Function called by the transport for each received message.
+ *
+ * @param cls closure
+ * @param receiver receiver of the message
+ * @param sender sender of the message
+ * @param message the message
+ */
+typedef void
+(*GNUNET_TRANSPORT_TESTING_ReceiveCallback) (void *cls,
+ struct GNUNET_TRANSPORT_TESTING_PeerContext *receiver,
+ const struct GNUNET_PeerIdentity *sender,
+ const struct GNUNET_MessageHeader *message);
+
+
+/**
+ * Function called to notify transport users that another
+ * peer connected to us.
+ *
+ * @param cls closure
+ * @param me peer experiencing the event
+ * @param other peer that connected to @a me
+ */
+typedef void
+(*GNUNET_TRANSPORT_TESTING_NotifyConnect) (void *cls,
+ struct GNUNET_TRANSPORT_TESTING_PeerContext *me,
+ const struct GNUNET_PeerIdentity *other);
+
+
+/**
+ * Function called to notify transport users that another
+ * peer disconnected from us.
+ *
+ * @param cls closure
+ * @param me peer experiencing the event
+ * @param other peer that disconnected from @a me
+ */
+typedef void
+(*GNUNET_TRANSPORT_TESTING_NotifyDisconnect) (void *cls,
+ struct GNUNET_TRANSPORT_TESTING_PeerContext *me,
+ const struct GNUNET_PeerIdentity *other);
+
+
+/**
+ * Closure that must be passed to
+ * #GNUNET_TRANSPORT_TESTING_connect_check.
+ */
+struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext
+{
+
+ /**
+ * How should we continue after the connect?
+ */
+ GNUNET_SCHEDULER_TaskCallback connect_continuation;
+
+ /**
+ * Closure for @e connect_continuation.
+ */
+ void *connect_continuation_cls;
+
+ /**
+ * Which configuration file should we pass to the
+ * #GNUNET_PROGRAM_run() of the testcase?
+ */
+ const char *config_file;
+
+ /**
+ * Receiver argument to give for peers we start.
+ */
+ GNUNET_TRANSPORT_TESTING_ReceiveCallback rec;
+
+ /**
+ * Notify connect argument to give for peers we start.
+ */
+ GNUNET_TRANSPORT_TESTING_NotifyConnect nc;
+
+ /**
+ * Notify disconnect argument to give for peers we start.
+ */
+ GNUNET_TRANSPORT_TESTING_NotifyDisconnect nd;
+
+ /**
+ * Closure for @e rec, @e nc and @e nd.
+ */
+ void *cls;
+
+ /**
+ * Custom task to run on shutdown.
+ */
+ GNUNET_SCHEDULER_TaskCallback shutdown_task;
+
+ /**
+ * Closure for @e shutdown_task.
+ */
+ void *shutdown_task_cls;
+
+ /**
+ * When should the testcase time out?
+ */
+ struct GNUNET_TIME_Relative timeout;
+
+ /* ******* fields set by #GNUNET_TRANSPORT_TESTING_connect_check **** */
+
+ /**
+ * Number of peers involved in the test.
+ */
+ unsigned int num_peers;
+
+ /**
+ * Configuration files we have, array with @e num_peers entries.
+ */
+ char **cfg_files;
+
+ /**
+ * Array with @e num_peers entries.
+ */
+ struct GNUNET_TRANSPORT_TESTING_PeerContext **p;
+
+ /**
+ * Name of the plugin.
+ */
+ const char *test_plugin;
+
+ /**
+ * Name of the testcase.
+ */
+ const char *test_name;
+
+ /**
+ * Configuration object for the testcase.
+ */
+ const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+ /**
+ * Main testing handle.
+ */
+ struct GNUNET_TRANSPORT_TESTING_Handle *tth;
+
+ /**
+ * Result from the main function, set to #GNUNET_OK on success.
+ * Clients should set to #GNUNET_SYSERR to indicate test failure.
+ */
+ int global_ret;
+
+ /* ******* internal state, clients should not mess with this **** */
+
+ /**
+ * Task run on timeout.
+ */
+ struct GNUNET_SCHEDULER_Task *timeout_task;
+
+ /**
+ * Number of peers that have been started.
+ */
+ unsigned int started;
+
+ /**
+ * DLL of active connect requests.
+ */
+ struct GNUNET_TRANSPORT_TESTING_ConnectRequestList *crl_head;
+
+ /**
+ * DLL of active connect requests.
+ */
+ struct GNUNET_TRANSPORT_TESTING_ConnectRequestList *crl_tail;
+
+ /**
+ * Array with @e num_peers entries.
+ */
+ struct GNUNET_TRANSPORT_TESTING_InternalPeerContext *ip;
+
+};
+
+
+/**
+ * Find peer by peer ID.
+ *
+ * @param ccc context to search
+ * @param peer peer to look for
+ * @return NULL if @a peer was not found
+ */
+struct GNUNET_TRANSPORT_TESTING_PeerContext *
+GNUNET_TRANSPORT_TESTING_find_peer (struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc,
+ const struct GNUNET_PeerIdentity *peer);
+
+
+/**
+ * Common implementation of the #GNUNET_TRANSPORT_TESTING_CheckCallback.
+ * Starts and connects the two peers, then invokes the
+ * `connect_continuation` from @a cls. Sets up a timeout to
+ * abort the test, and a shutdown handler to clean up properly
+ * on exit.
+ *
+ * @param cls closure of type `struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext`
+ * @param tth_ initialized testing handle
+ * @param test_plugin_ name of the plugin
+ * @param test_name_ name of the test
+ * @param num_peers number of entries in the @a cfg_file array
+ * @param cfg_files array of names of configuration files for the peers
+ * @return #GNUNET_SYSERR on error
+ */
+int
+GNUNET_TRANSPORT_TESTING_connect_check (void *cls,
+ struct GNUNET_TRANSPORT_TESTING_Handle *tth_,
+ const char *test_plugin_,
+ const char *test_name_,
+ unsigned int num_peers,
+ char *cfg_files[]);
+
+
/**
* Main function of a testcase. Called with the initial setup data
* for the test as derived from the source name and the binary name.
*
* @param cls closure
- * @param tth initialized testing handle
- * @param test_plugin name of the plugin (if available)
+ * @param tth_ initialized testing handle
+ * @param test_plugin_ name of the plugin
+ * @param test_name_ name of the test
* @param num_peers number of entries in the @a cfg_file array
* @param cfg_files array of names of configuration files for the peers
+ * @return #GNUNET_SYSERR on error
*/
-typedef void
+typedef int
(*GNUNET_TRANSPORT_TESTING_CheckCallback)(void *cls,
- struct GNUNET_TRANSPORT_TESTING_Handle *tth,
- const char *test_plugin,
+ struct GNUNET_TRANSPORT_TESTING_Handle *tth_,
+ const char *test_plugin_,
+ const char *test_name_,
unsigned int num_peers,
- const char *cfg_files[]);
+ char *cfg_files[]);
/**
GNUNET_TRANSPORT_TESTING_main_ (argv[0], __FILE__, num_peers, check, check_cls)
+
+/* ********************** log-only convenience functions ************* */
+
+
+/**
+ * Log a connect event.
+ *
+ * @param cls NULL
+ * @param me peer that had the event
+ * @param other peer that connected.
+ */
+void
+GNUNET_TRANSPORT_TESTING_log_connect (void *cls,
+ struct GNUNET_TRANSPORT_TESTING_PeerContext *me,
+ const struct GNUNET_PeerIdentity *other);
+
+
+/**
+ * Log a disconnect event.
+ *
+ * @param cls NULL
+ * @param me peer that had the event
+ * @param other peer that disconnected.
+ */
+void
+GNUNET_TRANSPORT_TESTING_log_disconnect (void *cls,
+ struct GNUNET_TRANSPORT_TESTING_PeerContext *me,
+ const struct GNUNET_PeerIdentity *other);
+
+
+
/* ********************** low-level filename functions *************** */