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 ( \
36 GNUNET_TIME_UNIT_MILLISECONDS, 1)
38 static unsigned int received_cnt;
41 GNUNET_NETWORK_STRUCT_BEGIN
45 struct GNUNET_MessageHeader header;
46 uint32_t x GNUNET_PACKED;
49 GNUNET_NETWORK_STRUCT_END
51 static int global_ret;
53 static struct GNUNET_SCHEDULER_Task *tt;
55 static struct GNUNET_SCHEDULER_Task *dt;
57 static struct GNUNET_MQ_Handle *cmq;
61 do_shutdown (void *cls)
66 GNUNET_SCHEDULER_cancel (tt);
71 GNUNET_MQ_destroy (cmq);
78 do_timeout (void *cls)
82 GNUNET_SCHEDULER_shutdown ();
88 * Generic error handler, called with the appropriate
89 * error code and the same closure specified at the creation of
91 * Not every message queue implementation supports an error handler.
94 * @param error error code
98 enum GNUNET_MQ_Error error)
102 GNUNET_SCHEDULER_shutdown ();
107 client_continue (void *cls)
109 struct GNUNET_SERVICE_Client *c = cls;
112 GNUNET_SERVICE_client_continue (c);
117 handle_dummy (void *cls,
118 const struct MyMessage *msg)
120 struct GNUNET_SERVICE_Client *c = cls;
122 GNUNET_assert (NULL == dt);
123 /* artificially make receiver slower than sender */
124 dt = GNUNET_SCHEDULER_add_delayed (RECEIVER_THROTTLE,
127 if (received_cnt != ntohl (msg->x))
131 GNUNET_SCHEDULER_shutdown ();
138 handle_dummy2 (void *cls,
139 const struct MyMessage *msg)
141 struct GNUNET_SERVICE_Client *c = cls;
143 GNUNET_SERVICE_client_continue (c);
144 if (NUM_TRANSMISSIONS != received_cnt)
149 GNUNET_SCHEDULER_shutdown ();
154 * Function called whenever MQ has sent a message.
157 notify_sent_cb (void *cls)
159 static unsigned int seen;
160 unsigned int *cnt = cls;
166 GNUNET_SCHEDULER_shutdown ();
174 * Start running the actual test.
176 * @param cls closure passed to #GNUNET_SERVICE_MAIN
177 * @param cfg configuration to use for this service
178 * @param sh handle to the newly create service
182 const struct GNUNET_CONFIGURATION_Handle *cfg,
183 struct GNUNET_SERVICE_Handle *sh)
185 struct GNUNET_MQ_MessageHandler ch[] = {
186 GNUNET_MQ_handler_end ()
188 struct GNUNET_MQ_Envelope *env;
193 cmq = GNUNET_CLIENT_connect (cfg,
198 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
200 tt = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
203 for (unsigned int i = 0; i < NUM_TRANSMISSIONS; i++)
207 cnt = GNUNET_new (unsigned int);
209 env = GNUNET_MQ_msg (m,
210 GNUNET_MESSAGE_TYPE_DUMMY);
211 GNUNET_MQ_notify_sent (env,
218 env = GNUNET_MQ_msg (m,
219 GNUNET_MESSAGE_TYPE_DUMMY2);
226 * Callback to be called when a client connects to the service.
228 * @param cls closure for the service
229 * @param c the new client that connected to the service
230 * @param mq the message queue used to send messages to the client
231 * @return the client-specific (`internal') closure
234 connect_cb (void *cls,
235 struct GNUNET_SERVICE_Client *c,
236 struct GNUNET_MQ_Handle *mq)
245 * Callback to be called when a client disconnected from the service
247 * @param cls closure for the service
248 * @param c the client that disconnected
249 * @param internal_cls the client-specific (`internal') closure
252 disconnect_cb (void *cls,
253 struct GNUNET_SERVICE_Client *c,
265 struct GNUNET_MQ_Envelope *mqm;
266 struct MyMessage *mm;
271 mqm = GNUNET_MQ_msg (mm,
272 GNUNET_MESSAGE_TYPE_DUMMY);
273 GNUNET_assert (NULL != mqm);
274 GNUNET_assert (NULL != mm);
275 GNUNET_assert (GNUNET_MESSAGE_TYPE_DUMMY == ntohs (mm->header.type));
276 GNUNET_assert (sizeof(struct MyMessage) == ntohs (mm->header.size));
277 GNUNET_MQ_discard (mqm);
284 struct GNUNET_MQ_Envelope *mqm;
285 struct GNUNET_MessageHeader *mh;
287 mqm = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_DUMMY);
288 /* how could the above be checked? */
290 GNUNET_MQ_discard (mqm);
292 mqm = GNUNET_MQ_msg_header_extra (mh,
294 GNUNET_MESSAGE_TYPE_DUMMY);
295 GNUNET_assert (GNUNET_MESSAGE_TYPE_DUMMY == ntohs (mh->type));
296 GNUNET_assert (sizeof(struct GNUNET_MessageHeader) + 20 == ntohs (mh->size));
297 GNUNET_MQ_discard (mqm);
302 main (int argc, char **argv)
304 char *test_argv[] = {
305 (char *) "test_client",
307 "test_client_data.conf",
310 struct GNUNET_MQ_MessageHandler mh[] = {
311 GNUNET_MQ_hd_fixed_size (dummy,
312 GNUNET_MESSAGE_TYPE_DUMMY,
315 GNUNET_MQ_hd_fixed_size (dummy2,
316 GNUNET_MESSAGE_TYPE_DUMMY2,
319 GNUNET_MQ_handler_end ()
324 GNUNET_log_setup ("test-mq",
330 GNUNET_SERVICE_run_ (3,
333 GNUNET_SERVICE_OPTION_NONE,