2 This file is part of GNUnet.
3 Copyright (C) 2012, 2018 GNUnet e.V.
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
22 * @file util/test_mq.c
24 * @author Florian Dold
25 * @author Christian Grothoff
28 #include "gnunet_util_lib.h"
30 #define NUM_TRANSMISSIONS 500
33 * How long does the receiver take per message?
35 #define RECEIVER_THROTTLE GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 1)
37 static unsigned int received_cnt;
40 GNUNET_NETWORK_STRUCT_BEGIN
44 struct GNUNET_MessageHeader header;
45 uint32_t x GNUNET_PACKED;
48 GNUNET_NETWORK_STRUCT_END
50 static int global_ret;
52 static struct GNUNET_SCHEDULER_Task *tt;
54 static struct GNUNET_SCHEDULER_Task *dt;
56 static struct GNUNET_MQ_Handle *cmq;
60 do_shutdown (void *cls)
65 GNUNET_SCHEDULER_cancel (tt);
70 GNUNET_MQ_destroy (cmq);
77 do_timeout (void *cls)
81 GNUNET_SCHEDULER_shutdown ();
87 * Generic error handler, called with the appropriate
88 * error code and the same closure specified at the creation of
90 * Not every message queue implementation supports an error handler.
93 * @param error error code
97 enum GNUNET_MQ_Error error)
101 GNUNET_SCHEDULER_shutdown ();
106 client_continue (void *cls)
108 struct GNUNET_SERVICE_Client *c = cls;
111 GNUNET_SERVICE_client_continue (c);
116 handle_dummy (void *cls,
117 const struct MyMessage *msg)
119 struct GNUNET_SERVICE_Client *c = cls;
121 GNUNET_assert (NULL == dt);
122 /* artificially make receiver slower than sender */
123 dt = GNUNET_SCHEDULER_add_delayed (RECEIVER_THROTTLE,
126 if (received_cnt != ntohl (msg->x))
130 GNUNET_SCHEDULER_shutdown ();
137 handle_dummy2 (void *cls,
138 const struct MyMessage *msg)
140 struct GNUNET_SERVICE_Client *c = cls;
142 GNUNET_SERVICE_client_continue (c);
143 if (NUM_TRANSMISSIONS != received_cnt)
148 GNUNET_SCHEDULER_shutdown ();
153 * Function called whenever MQ has sent a message.
156 notify_sent_cb (void *cls)
158 static unsigned int seen;
159 unsigned int *cnt = cls;
165 GNUNET_SCHEDULER_shutdown ();
173 * Start running the actual test.
175 * @param cls closure passed to #GNUNET_SERVICE_MAIN
176 * @param cfg configuration to use for this service
177 * @param sh handle to the newly create service
181 const struct GNUNET_CONFIGURATION_Handle *cfg,
182 struct GNUNET_SERVICE_Handle *sh)
184 struct GNUNET_MQ_MessageHandler ch[] = {
185 GNUNET_MQ_handler_end ()
187 struct GNUNET_MQ_Envelope *env;
192 cmq = GNUNET_CLIENT_connect (cfg,
197 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
199 tt = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
202 for (unsigned int i=0;i<NUM_TRANSMISSIONS;i++)
206 cnt = GNUNET_new (unsigned int);
208 env = GNUNET_MQ_msg (m,
209 GNUNET_MESSAGE_TYPE_DUMMY);
210 GNUNET_MQ_notify_sent (env,
217 env = GNUNET_MQ_msg (m,
218 GNUNET_MESSAGE_TYPE_DUMMY2);
225 * Callback to be called when a client connects to the service.
227 * @param cls closure for the service
228 * @param c the new client that connected to the service
229 * @param mq the message queue used to send messages to the client
230 * @return the client-specific (`internal') closure
233 connect_cb (void *cls,
234 struct GNUNET_SERVICE_Client *c,
235 struct GNUNET_MQ_Handle *mq)
244 * Callback to be called when a client disconnected from the service
246 * @param cls closure for the service
247 * @param c the client that disconnected
248 * @param internal_cls the client-specific (`internal') closure
251 disconnect_cb (void *cls,
252 struct GNUNET_SERVICE_Client *c,
264 struct GNUNET_MQ_Envelope *mqm;
265 struct MyMessage *mm;
270 mqm = GNUNET_MQ_msg (mm,
271 GNUNET_MESSAGE_TYPE_DUMMY);
272 GNUNET_assert (NULL != mqm);
273 GNUNET_assert (NULL != mm);
274 GNUNET_assert (GNUNET_MESSAGE_TYPE_DUMMY == ntohs (mm->header.type));
275 GNUNET_assert (sizeof (struct MyMessage) == ntohs (mm->header.size));
276 GNUNET_MQ_discard (mqm);
283 struct GNUNET_MQ_Envelope *mqm;
284 struct GNUNET_MessageHeader *mh;
286 mqm = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_DUMMY);
287 /* how could the above be checked? */
289 GNUNET_MQ_discard (mqm);
291 mqm = GNUNET_MQ_msg_header_extra (mh,
293 GNUNET_MESSAGE_TYPE_DUMMY);
294 GNUNET_assert (GNUNET_MESSAGE_TYPE_DUMMY == ntohs (mh->type));
295 GNUNET_assert (sizeof (struct GNUNET_MessageHeader) + 20 == ntohs (mh->size));
296 GNUNET_MQ_discard (mqm);
301 main (int argc, char **argv)
303 char * test_argv[] = {
304 (char *) "test_client",
306 "test_client_data.conf",
309 struct GNUNET_MQ_MessageHandler mh[] = {
310 GNUNET_MQ_hd_fixed_size (dummy,
311 GNUNET_MESSAGE_TYPE_DUMMY,
314 GNUNET_MQ_hd_fixed_size (dummy2,
315 GNUNET_MESSAGE_TYPE_DUMMY2,
318 GNUNET_MQ_handler_end ()
323 GNUNET_log_setup ("test-mq",
329 GNUNET_SERVICE_run_ (3,
332 GNUNET_SERVICE_OPTION_NONE,