From 3915b341a6218c6a6a1b1261ae69d8cf56b424e6 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 8 May 2018 12:42:15 +0200 Subject: [PATCH] expand test_mq testcase --- src/include/gnunet_protocols.h | 5 + src/util/test_mq.c | 276 +++++++++++++++++++++++++++++++-- 2 files changed, 271 insertions(+), 10 deletions(-) diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 1ef00cfc8..c5e45d5c1 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h @@ -66,6 +66,11 @@ extern "C" */ #define GNUNET_MESSAGE_TYPE_DUMMY 2 +/** + * Another dummy messages for testing / benchmarking. + */ +#define GNUNET_MESSAGE_TYPE_DUMMY2 3 + /******************************************************************************* * RESOLVER message types ******************************************************************************/ diff --git a/src/util/test_mq.c b/src/util/test_mq.c index 9e8fc844e..533cb8af3 100644 --- a/src/util/test_mq.c +++ b/src/util/test_mq.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2012 GNUnet e.V. + Copyright (C) 2012, 2018 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 @@ -20,11 +20,22 @@ /** * @file util/test_mq.c - * @brief simple tests for mq + * @brief tests for mq + * @author Florian Dold + * @author Christian Grothoff */ #include "platform.h" #include "gnunet_util_lib.h" +#define NUM_TRANSMISSIONS 500 + +/** + * How long does the receiver take per message? + */ +#define RECEIVER_THROTTLE GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 1) + +static unsigned int received_cnt; + GNUNET_NETWORK_STRUCT_BEGIN @@ -36,6 +47,216 @@ struct MyMessage GNUNET_NETWORK_STRUCT_END +static int global_ret; + +static struct GNUNET_SCHEDULER_Task *tt; + +static struct GNUNET_SCHEDULER_Task *dt; + +static struct GNUNET_MQ_Handle *cmq; + + +static void +do_shutdown (void *cls) +{ + (void) cls; + if (NULL != tt) + { + GNUNET_SCHEDULER_cancel (tt); + tt = NULL; + } + if (NULL != cmq) + { + GNUNET_MQ_destroy (cmq); + cmq = NULL; + } +} + + +static void +do_timeout (void *cls) +{ + (void) cls; + tt = NULL; + GNUNET_SCHEDULER_shutdown (); + global_ret = 1; +} + + +/** + * Generic error handler, called with the appropriate + * error code and the same closure specified at the creation of + * the message queue. + * Not every message queue implementation supports an error handler. + * + * @param cls closure + * @param error error code + */ +static void +error_cb (void *cls, + enum GNUNET_MQ_Error error) +{ + GNUNET_break (0); + global_ret = 3; + GNUNET_SCHEDULER_shutdown (); +} + + +static void +client_continue (void *cls) +{ + struct GNUNET_SERVICE_Client *c = cls; + + dt = NULL; + GNUNET_SERVICE_client_continue (c); +} + + +static void +handle_dummy (void *cls, + const struct MyMessage *msg) +{ + struct GNUNET_SERVICE_Client *c = cls; + + GNUNET_assert (NULL == dt); + /* artificially make receiver slower than sender */ + dt = GNUNET_SCHEDULER_add_delayed (RECEIVER_THROTTLE, + &client_continue, + c); + if (received_cnt != ntohl (msg->x)) + { + GNUNET_break (0); + global_ret = 4; + GNUNET_SCHEDULER_shutdown (); + } + received_cnt++; +} + + +static void +handle_dummy2 (void *cls, + const struct MyMessage *msg) +{ + struct GNUNET_SERVICE_Client *c = cls; + + GNUNET_SERVICE_client_continue (c); + if (NUM_TRANSMISSIONS != received_cnt) + { + GNUNET_break (0); + global_ret = 5; + } + GNUNET_SCHEDULER_shutdown (); +} + + +/** + * Function called whenever MQ has sent a message. + */ +static void +notify_sent_cb (void *cls) +{ + static unsigned int seen; + unsigned int *cnt = cls; + + if (seen != *cnt) + { + GNUNET_break (0); + global_ret = 6; + GNUNET_SCHEDULER_shutdown (); + } + seen++; + GNUNET_free (cnt); +} + + +/** + * Start running the actual test. + * + * @param cls closure passed to #GNUNET_SERVICE_MAIN + * @param cfg configuration to use for this service + * @param sh handle to the newly create service + */ +static void +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_SERVICE_Handle *sh) +{ + struct GNUNET_MQ_MessageHandler ch[] = { + GNUNET_MQ_handler_end () + }; + struct GNUNET_MQ_Envelope *env; + struct MyMessage *m; + + (void) cls; + (void) sh; + cmq = GNUNET_CLIENT_connect (cfg, + "test_client", + ch, + &error_cb, + NULL); + GNUNET_SCHEDULER_add_shutdown (&do_shutdown, + NULL); + tt = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, + &do_timeout, + NULL); + for (unsigned int i=0;ix = htonl (i); + GNUNET_MQ_send (cmq, + env); + } + env = GNUNET_MQ_msg (m, + GNUNET_MESSAGE_TYPE_DUMMY2); + GNUNET_MQ_send (cmq, + env); +} + + +/** + * Callback to be called when a client connects to the service. + * + * @param cls closure for the service + * @param c the new client that connected to the service + * @param mq the message queue used to send messages to the client + * @return the client-specific (`internal') closure + */ +static void * +connect_cb (void *cls, + struct GNUNET_SERVICE_Client *c, + struct GNUNET_MQ_Handle *mq) +{ + (void) cls; + (void) mq; + return c; +} + + +/** + * Callback to be called when a client disconnected from the service + * + * @param cls closure for the service + * @param c the client that disconnected + * @param internal_cls the client-specific (`internal') closure + */ +static void +disconnect_cb (void *cls, + struct GNUNET_SERVICE_Client *c, + void *internal_cls) +{ + (void) cls; + (void) c; + (void) internal_cls; +} + static void test1 () @@ -46,10 +267,11 @@ test1 () mm = NULL; mqm = NULL; - mqm = GNUNET_MQ_msg (mm, 42); + mqm = GNUNET_MQ_msg (mm, + GNUNET_MESSAGE_TYPE_DUMMY); GNUNET_assert (NULL != mqm); GNUNET_assert (NULL != mm); - GNUNET_assert (42 == ntohs (mm->header.type)); + GNUNET_assert (GNUNET_MESSAGE_TYPE_DUMMY == ntohs (mm->header.type)); GNUNET_assert (sizeof (struct MyMessage) == ntohs (mm->header.size)); GNUNET_MQ_discard (mqm); } @@ -61,13 +283,15 @@ test2 () struct GNUNET_MQ_Envelope *mqm; struct GNUNET_MessageHeader *mh; - mqm = GNUNET_MQ_msg_header (42); + mqm = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_DUMMY); /* how could the above be checked? */ GNUNET_MQ_discard (mqm); - mqm = GNUNET_MQ_msg_header_extra (mh, 20, 42); - GNUNET_assert (42 == ntohs (mh->type)); + mqm = GNUNET_MQ_msg_header_extra (mh, + 20, + GNUNET_MESSAGE_TYPE_DUMMY); + GNUNET_assert (GNUNET_MESSAGE_TYPE_DUMMY == ntohs (mh->type)); GNUNET_assert (sizeof (struct GNUNET_MessageHeader) + 20 == ntohs (mh->size)); GNUNET_MQ_discard (mqm); } @@ -76,9 +300,41 @@ test2 () int main (int argc, char **argv) { - GNUNET_log_setup ("test-mq", "INFO", NULL); + char * test_argv[] = { + (char *) "test_client", + "-c", + "test_client_data.conf", + NULL + }; + struct GNUNET_MQ_MessageHandler mh[] = { + GNUNET_MQ_hd_fixed_size (dummy, + GNUNET_MESSAGE_TYPE_DUMMY, + struct MyMessage, + NULL), + GNUNET_MQ_hd_fixed_size (dummy2, + GNUNET_MESSAGE_TYPE_DUMMY2, + struct MyMessage, + NULL), + GNUNET_MQ_handler_end () + }; + + (void) argc; + (void) argv; + GNUNET_log_setup ("test-mq", + "INFO", + NULL); test1 (); test2 (); - return 0; + if (0 != + GNUNET_SERVICE_run_ (3, + test_argv, + "test_client", + GNUNET_SERVICE_OPTION_NONE, + &run, + &connect_cb, + &disconnect_cb, + NULL, + mh)) + return 1; + return global_ret; } - -- 2.25.1