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.
17 * @file util/test_mq.c
19 * @author Florian Dold
20 * @author Christian Grothoff
23 #include "gnunet_util_lib.h"
25 #define NUM_TRANSMISSIONS 500
28 * How long does the receiver take per message?
30 #define RECEIVER_THROTTLE GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 1)
32 static unsigned int received_cnt;
35 GNUNET_NETWORK_STRUCT_BEGIN
39 struct GNUNET_MessageHeader header;
40 uint32_t x GNUNET_PACKED;
43 GNUNET_NETWORK_STRUCT_END
45 static int global_ret;
47 static struct GNUNET_SCHEDULER_Task *tt;
49 static struct GNUNET_SCHEDULER_Task *dt;
51 static struct GNUNET_MQ_Handle *cmq;
55 do_shutdown (void *cls)
60 GNUNET_SCHEDULER_cancel (tt);
65 GNUNET_MQ_destroy (cmq);
72 do_timeout (void *cls)
76 GNUNET_SCHEDULER_shutdown ();
82 * Generic error handler, called with the appropriate
83 * error code and the same closure specified at the creation of
85 * Not every message queue implementation supports an error handler.
88 * @param error error code
92 enum GNUNET_MQ_Error error)
96 GNUNET_SCHEDULER_shutdown ();
101 client_continue (void *cls)
103 struct GNUNET_SERVICE_Client *c = cls;
106 GNUNET_SERVICE_client_continue (c);
111 handle_dummy (void *cls,
112 const struct MyMessage *msg)
114 struct GNUNET_SERVICE_Client *c = cls;
116 GNUNET_assert (NULL == dt);
117 /* artificially make receiver slower than sender */
118 dt = GNUNET_SCHEDULER_add_delayed (RECEIVER_THROTTLE,
121 if (received_cnt != ntohl (msg->x))
125 GNUNET_SCHEDULER_shutdown ();
132 handle_dummy2 (void *cls,
133 const struct MyMessage *msg)
135 struct GNUNET_SERVICE_Client *c = cls;
137 GNUNET_SERVICE_client_continue (c);
138 if (NUM_TRANSMISSIONS != received_cnt)
143 GNUNET_SCHEDULER_shutdown ();
148 * Function called whenever MQ has sent a message.
151 notify_sent_cb (void *cls)
153 static unsigned int seen;
154 unsigned int *cnt = cls;
160 GNUNET_SCHEDULER_shutdown ();
168 * Start running the actual test.
170 * @param cls closure passed to #GNUNET_SERVICE_MAIN
171 * @param cfg configuration to use for this service
172 * @param sh handle to the newly create service
176 const struct GNUNET_CONFIGURATION_Handle *cfg,
177 struct GNUNET_SERVICE_Handle *sh)
179 struct GNUNET_MQ_MessageHandler ch[] = {
180 GNUNET_MQ_handler_end ()
182 struct GNUNET_MQ_Envelope *env;
187 cmq = GNUNET_CLIENT_connect (cfg,
192 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
194 tt = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
197 for (unsigned int i=0;i<NUM_TRANSMISSIONS;i++)
201 cnt = GNUNET_new (unsigned int);
203 env = GNUNET_MQ_msg (m,
204 GNUNET_MESSAGE_TYPE_DUMMY);
205 GNUNET_MQ_notify_sent (env,
212 env = GNUNET_MQ_msg (m,
213 GNUNET_MESSAGE_TYPE_DUMMY2);
220 * Callback to be called when a client connects to the service.
222 * @param cls closure for the service
223 * @param c the new client that connected to the service
224 * @param mq the message queue used to send messages to the client
225 * @return the client-specific (`internal') closure
228 connect_cb (void *cls,
229 struct GNUNET_SERVICE_Client *c,
230 struct GNUNET_MQ_Handle *mq)
239 * Callback to be called when a client disconnected from the service
241 * @param cls closure for the service
242 * @param c the client that disconnected
243 * @param internal_cls the client-specific (`internal') closure
246 disconnect_cb (void *cls,
247 struct GNUNET_SERVICE_Client *c,
259 struct GNUNET_MQ_Envelope *mqm;
260 struct MyMessage *mm;
265 mqm = GNUNET_MQ_msg (mm,
266 GNUNET_MESSAGE_TYPE_DUMMY);
267 GNUNET_assert (NULL != mqm);
268 GNUNET_assert (NULL != mm);
269 GNUNET_assert (GNUNET_MESSAGE_TYPE_DUMMY == ntohs (mm->header.type));
270 GNUNET_assert (sizeof (struct MyMessage) == ntohs (mm->header.size));
271 GNUNET_MQ_discard (mqm);
278 struct GNUNET_MQ_Envelope *mqm;
279 struct GNUNET_MessageHeader *mh;
281 mqm = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_DUMMY);
282 /* how could the above be checked? */
284 GNUNET_MQ_discard (mqm);
286 mqm = GNUNET_MQ_msg_header_extra (mh,
288 GNUNET_MESSAGE_TYPE_DUMMY);
289 GNUNET_assert (GNUNET_MESSAGE_TYPE_DUMMY == ntohs (mh->type));
290 GNUNET_assert (sizeof (struct GNUNET_MessageHeader) + 20 == ntohs (mh->size));
291 GNUNET_MQ_discard (mqm);
296 main (int argc, char **argv)
298 char * test_argv[] = {
299 (char *) "test_client",
301 "test_client_data.conf",
304 struct GNUNET_MQ_MessageHandler mh[] = {
305 GNUNET_MQ_hd_fixed_size (dummy,
306 GNUNET_MESSAGE_TYPE_DUMMY,
309 GNUNET_MQ_hd_fixed_size (dummy2,
310 GNUNET_MESSAGE_TYPE_DUMMY2,
313 GNUNET_MQ_handler_end ()
318 GNUNET_log_setup ("test-mq",
324 GNUNET_SERVICE_run_ (3,
327 GNUNET_SERVICE_OPTION_NONE,