From 08669dc96bde16224d1dfc5eb5f790b93c93fb88 Mon Sep 17 00:00:00 2001 From: Sree Harsha Totakura Date: Fri, 6 Jul 2012 15:13:24 +0000 Subject: testbed api test case and fixes --- src/testbed/Makefile.am | 10 +- src/testbed/gnunet-service-testbed.c | 62 +++++++++--- src/testbed/test_testbed_api.c | 177 +++++++++++++++++++++++++++++++++++ src/testbed/test_testbed_api.conf | 8 +- src/testbed/testbed_api.c | 49 +++++++--- 5 files changed, 279 insertions(+), 27 deletions(-) create mode 100644 src/testbed/test_testbed_api.c (limited to 'src/testbed') diff --git a/src/testbed/Makefile.am b/src/testbed/Makefile.am index e8ca96081..8a3912f5b 100644 --- a/src/testbed/Makefile.am +++ b/src/testbed/Makefile.am @@ -51,7 +51,8 @@ libgnunettestbed_la_LDFLAGS = \ -version-info 0:0:0 check_PROGRAMS = \ - test_testbed_api_hosts + test_testbed_api_hosts \ + test_testbed_api if ENABLE_TEST_RUN TESTS = $(check_PROGRAMS) @@ -61,4 +62,11 @@ test_testbed_api_hosts_SOURCES = \ test_testbed_api_hosts.c test_testbed_api_hosts_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ + libgnunettestbed.la + +test_testbed_api_SOURCES = \ + test_testbed_api.c +test_testbed_api_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testing/libgnunettesting.la \ libgnunettestbed.la \ No newline at end of file diff --git a/src/testbed/gnunet-service-testbed.c b/src/testbed/gnunet-service-testbed.c index 7cc822aca..a89ae405c 100644 --- a/src/testbed/gnunet-service-testbed.c +++ b/src/testbed/gnunet-service-testbed.c @@ -422,14 +422,18 @@ static int host_list_add (struct GNUNET_TESTBED_Host *host) { uint32_t host_id; - + uint32_t new_size; + host_id = GNUNET_TESTBED_host_get_id_ (host); if (host_list_size <= host_id) { + new_size = host_list_size + LIST_GROW_STEP; host_list = GNUNET_realloc (host_list, sizeof (struct GNUNET_TESTBED_Host *) - * (host_id + 10)); - host_list_size += (host_id + 10); + * new_size); + memset (&host_list[host_list_size], 0, + sizeof (struct Slave *) * LIST_GROW_STEP); + host_list_size = new_size; } if (NULL != host_list[host_id]) { @@ -449,17 +453,46 @@ host_list_add (struct GNUNET_TESTBED_Host *host) static void route_list_add (struct Route *route) { - if (route->dest > route_list_size) + uint32_t new_size; + + if (route->dest >= route_list_size) { - route_list_size += LIST_GROW_STEP; + new_size = route_list_size + LIST_GROW_STEP; route_list = GNUNET_realloc (route_list, sizeof (struct Route *) - * route_list_size); + * new_size); + memset (&route_list[route_list_size], 0, + sizeof (struct Slave *) * LIST_GROW_STEP); + route_list_size = new_size; } GNUNET_assert (NULL == route_list[route->dest]); route_list[route->dest] = route; } +/** + * Adds a slave to the slave array + * + * @param route the route to add + */ +static void +slave_list_add (struct Slave *slave) +{ + uint32_t new_size; + + if (slave->host_id >= slave_list_size) + { + new_size = slave_list_size + LIST_GROW_STEP; + slave_list = GNUNET_realloc (slave_list, sizeof (struct Slave *) + * new_size); + memset (&slave_list[slave_list_size], 0, + sizeof (struct Slave *) * LIST_GROW_STEP); + slave_list_size = new_size; + } + GNUNET_assert (NULL == slave_list[slave->host_id]); + slave_list[slave->host_id] = slave; +} + + /** * Routes message to a host given its host_id * @@ -657,7 +690,7 @@ handle_add_host (void *cls, } hostname_length = ntohs (message->size) - (sizeof (struct GNUNET_TESTBED_AddHostMessage) + username_length); - if (strlen (hostname) != hostname_length) + if (strlen (hostname) != hostname_length - 1) { GNUNET_break (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); @@ -667,7 +700,8 @@ handle_add_host (void *cls, LOG_DEBUG ("Received ADDHOST message\n"); LOG_DEBUG ("-------host id: %u\n", host_id); if (NULL != hostname) LOG_DEBUG ("-------hostname: %s\n", hostname); - if (NULL != username) LOG_DEBUG ("-------username: %s\n", username); + if (0 != username_length) LOG_DEBUG ("-------username: %s\n", username); + else LOG_DEBUG ("-------username: NULL\n"); LOG_DEBUG ("-------ssh port: %u\n", ntohs (msg->ssh_port)); host = GNUNET_TESTBED_host_create_with_id (host_id, hostname, username, ntohs (msg->ssh_port)); @@ -887,15 +921,16 @@ handle_link_controllers (void *cls, return; } GNUNET_free (config); - if (delegated_host_id >= slave_list_size) + if ((delegated_host_id < slave_list_size) && + (NULL != slave_list[delegated_host_id])) { - slave_list_size += LIST_GROW_STEP; - slave_list = GNUNET_realloc (slave_list, - sizeof (struct Slave *) * slave_list_size); + GNUNET_break (0); /* Configuration parsing error */ + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; } slave = GNUNET_malloc (sizeof (struct Slave)); slave->host_id = delegated_host_id; - slave_list[delegated_host_id] = slave; + slave_list_add (slave); if (1 == msg->is_subordinate) { slave->controller_proc = @@ -1113,6 +1148,7 @@ testbed_run (void *cls, fh, &shutdown_task, NULL); + LOG_DEBUG ("Testbed startup complete\n"); } diff --git a/src/testbed/test_testbed_api.c b/src/testbed/test_testbed_api.c new file mode 100644 index 000000000..612b30347 --- /dev/null +++ b/src/testbed/test_testbed_api.c @@ -0,0 +1,177 @@ +/* + This file is part of GNUnet + (C) 2008--2012 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 testbed/test_testbed_api.c + * @brief testcases for the testbed api + * @author Sree Harsha Totakura + */ + +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_testing_lib-new.h" +#include "gnunet_testbed_service.h" + + +/** + * Generic logging shortcut + */ +#define LOG(kind,...) \ + GNUNET_log (kind, __VA_ARGS__) + + +/** + * Our localhost + */ +static struct GNUNET_TESTBED_Host *host; + +/** + * The controller handle + */ +static struct GNUNET_TESTBED_Controller *c; + +/** + * A neighbouring host + */ +static struct GNUNET_TESTBED_Host *neighbour; + +/** + * Handle for neighbour registration + */ +static struct GNUNET_TESTBED_HostRegistrationHandle *reg_handle; + +/** + * Abort task identifier + */ +static GNUNET_SCHEDULER_TaskIdentifier abort_task_id; + +/** + * The testing result + */ +static int result; + + +/** + * Shutdown nicely + * + * @param cls NULL + * @param tc the task context + */ +static void +do_shutdown (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (GNUNET_SCHEDULER_NO_TASK != abort_task_id) + GNUNET_SCHEDULER_cancel (abort_task_id); + if (NULL != reg_handle) + GNUNET_TESTBED_cancel_registration (reg_handle); + GNUNET_TESTBED_controller_disconnect (c); + GNUNET_TESTBED_host_destroy (neighbour); + GNUNET_TESTBED_host_destroy (host); +} + + +/** + * abort task to run on test timed out + * + * @param cls NULL + * @param tc the task context + */ +static void +do_abort (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + LOG (GNUNET_ERROR_TYPE_WARNING, "Test timedout -- Aborting\n"); + abort_task_id = GNUNET_SCHEDULER_NO_TASK; + do_shutdown (cls, tc); +} + + +/** + * Signature of the event handler function called by the + * respective event controller. + * + * @param cls closure + * @param event information about the event + */ +static void +controller_cb(void *cls, const struct GNUNET_TESTBED_EventInformation *event) +{ + GNUNET_break (0); +} + + +/** + * Callback which will be called to after a host registration succeeded or failed + * + * @param cls the host which has been registered + * @param emsg the error message; NULL if host registration is successful + */ +static void +registration_comp (void *cls, const char *emsg) +{ + GNUNET_assert (cls == neighbour); + reg_handle = NULL; + result = GNUNET_YES; + GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); +} + + +/** + * Main point of test execution + */ +static void +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTING_Peer *peer) +{ + uint64_t event_mask; + + host = GNUNET_TESTBED_host_create (NULL, NULL, 0); + GNUNET_assert (NULL != host); + event_mask ^= event_mask; /* NULL out */ + event_mask |= (1L << GNUNET_TESTBED_ET_PEER_START); + event_mask |= (1L << GNUNET_TESTBED_ET_PEER_STOP); + event_mask |= (1L << GNUNET_TESTBED_ET_CONNECT); + c = GNUNET_TESTBED_controller_connect (cfg, host, event_mask, + &controller_cb, NULL); + GNUNET_assert (NULL != c); + neighbour = GNUNET_TESTBED_host_create ("localhost", NULL, 0); + GNUNET_assert (NULL != neighbour); + reg_handle = + GNUNET_TESTBED_register_host (c, neighbour, ®istration_comp, neighbour); + GNUNET_assert (NULL != reg_handle); + + abort_task_id = GNUNET_SCHEDULER_add_delayed + (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 30), &do_abort, NULL); +} + + +/** + * Main function + */ +int main (int argc, char **argv) +{ + result = GNUNET_SYSERR; + if (0 != GNUNET_TESTING_service_run ("test_testbed_api", + "testbed", + "test_testbed_api.conf", + &run, NULL)) + return 1; + else return (GNUNET_OK == result) ? 0 : 1; +} diff --git a/src/testbed/test_testbed_api.conf b/src/testbed/test_testbed_api.conf index c41ee9539..bf6c414b8 100644 --- a/src/testbed/test_testbed_api.conf +++ b/src/testbed/test_testbed_api.conf @@ -1,5 +1,9 @@ -[lockmanager] -AUTOSTART = NO +[testbed] +AUTOSTART = NO +PORT = 12113 +ACCEPT_FROM = 127.0.0.1; +HOSTNAME = localhost +#PREFIX = xterm -geometry 100x85 -T peer1 -e libtool --mode=execute gdb --args [fs] AUTOSTART = NO diff --git a/src/testbed/testbed_api.c b/src/testbed/testbed_api.c index cd8e2249c..c0967dca3 100644 --- a/src/testbed/testbed_api.c +++ b/src/testbed/testbed_api.c @@ -48,6 +48,18 @@ #define LOG_DEBUG(...) \ LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__); +/** + * Relative time seconds shorthand + */ +#define TIME_REL_SECS(sec) \ + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, sec) + + +/** + * Default server message sending retry timeout + */ +#define TIMEOUT_REL TIME_REL_SECS(1) + /** * The message queue for sending messages to the controller service @@ -289,6 +301,7 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg) struct GNUNET_TESTBED_Controller *c = cls; int status; + c->in_receive = GNUNET_NO; /* FIXME: Add checks for message integrity */ if (NULL == msg) { @@ -306,12 +319,14 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg) default: GNUNET_break (0); } - if (GNUNET_OK == status) + if ((GNUNET_OK == status) && (GNUNET_NO == c->in_receive)) + { + c->in_receive = GNUNET_YES; GNUNET_CLIENT_receive (c->client, &message_handler, c, - GNUNET_TIME_UNIT_FOREVER_REL); + GNUNET_TIME_UNIT_FOREVER_REL); + } } - /** * Function called to notify a client about the connection begin ready to queue * more data. "buf" will be NULL and "size" zero if the connection was closed @@ -331,9 +346,22 @@ transmit_ready_notify (void *cls, size_t size, void *buf) c->th = NULL; mq_entry = c->mq_head; GNUNET_assert (NULL != mq_entry); + if ((0 == size) && (NULL == buf)) /* Timeout */ + { + LOG_DEBUG ("Message sending timed out -- retrying\n"); + c->th = + GNUNET_CLIENT_notify_transmit_ready (c->client, + ntohs (mq_entry->msg->size), + TIMEOUT_REL, + GNUNET_YES, &transmit_ready_notify, + c); + return 0; + } GNUNET_assert (ntohs (mq_entry->msg->size) <= size); - size = ntohs (mq_entry->msg->size); + size = ntohs (mq_entry->msg->size); memcpy (buf, mq_entry->msg, size); + LOG_DEBUG ("Message of type: %u and size: %u sent\n", + ntohs (mq_entry->msg->type), size); GNUNET_free (mq_entry->msg); GNUNET_CONTAINER_DLL_remove (c->mq_head, c->mq_tail, mq_entry); GNUNET_free (mq_entry); @@ -342,11 +370,10 @@ transmit_ready_notify (void *cls, size_t size, void *buf) c->th = GNUNET_CLIENT_notify_transmit_ready (c->client, ntohs (mq_entry->msg->size), - GNUNET_TIME_UNIT_FOREVER_REL, - GNUNET_NO, &transmit_ready_notify, + TIMEOUT_REL, + GNUNET_YES, &transmit_ready_notify, c); - if ( (GNUNET_NO == c->in_receive) && - (size > 0) ) + if (GNUNET_NO == c->in_receive) { c->in_receive = GNUNET_YES; GNUNET_CLIENT_receive (c->client, &message_handler, c, @@ -384,8 +411,8 @@ queue_message (struct GNUNET_TESTBED_Controller *controller, if (NULL == controller->th) controller->th = GNUNET_CLIENT_notify_transmit_ready (controller->client, size, - GNUNET_TIME_UNIT_FOREVER_REL, - GNUNET_NO, &transmit_ready_notify, + TIMEOUT_REL, + GNUNET_YES, &transmit_ready_notify, controller); } @@ -634,7 +661,7 @@ GNUNET_TESTBED_register_host (struct GNUNET_TESTBED_Controller *controller, msg->user_name_length = htons (user_name_length); if (NULL != username) memcpy (&msg[1], username, user_name_length); - strcpy (((void *) msg) + user_name_length, hostname); + strcpy (((void *) &msg[1]) + user_name_length, hostname); queue_message (controller, (struct GNUNET_MessageHeader *) msg); return rh; } -- cgit v1.2.3