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
43 struct GNUNET_MessageHeader header;
44 uint32_t x GNUNET_PACKED;
47 GNUNET_NETWORK_STRUCT_END
49 static int global_ret;
51 static struct GNUNET_SCHEDULER_Task *tt;
53 static struct GNUNET_SCHEDULER_Task *dt;
55 static struct GNUNET_MQ_Handle *cmq;
59 do_shutdown(void *cls)
64 GNUNET_SCHEDULER_cancel(tt);
69 GNUNET_MQ_destroy(cmq);
80 GNUNET_SCHEDULER_shutdown();
86 * Generic error handler, called with the appropriate
87 * error code and the same closure specified at the creation of
89 * Not every message queue implementation supports an error handler.
92 * @param error error code
96 enum GNUNET_MQ_Error error)
100 GNUNET_SCHEDULER_shutdown();
105 client_continue(void *cls)
107 struct GNUNET_SERVICE_Client *c = cls;
110 GNUNET_SERVICE_client_continue(c);
115 handle_dummy(void *cls,
116 const struct MyMessage *msg)
118 struct GNUNET_SERVICE_Client *c = cls;
120 GNUNET_assert(NULL == dt);
121 /* artificially make receiver slower than sender */
122 dt = GNUNET_SCHEDULER_add_delayed(RECEIVER_THROTTLE,
125 if (received_cnt != ntohl(msg->x))
129 GNUNET_SCHEDULER_shutdown();
136 handle_dummy2(void *cls,
137 const struct MyMessage *msg)
139 struct GNUNET_SERVICE_Client *c = cls;
141 GNUNET_SERVICE_client_continue(c);
142 if (NUM_TRANSMISSIONS != received_cnt)
147 GNUNET_SCHEDULER_shutdown();
152 * Function called whenever MQ has sent a message.
155 notify_sent_cb(void *cls)
157 static unsigned int seen;
158 unsigned int *cnt = cls;
164 GNUNET_SCHEDULER_shutdown();
172 * Start running the actual test.
174 * @param cls closure passed to #GNUNET_SERVICE_MAIN
175 * @param cfg configuration to use for this service
176 * @param sh handle to the newly create service
180 const struct GNUNET_CONFIGURATION_Handle *cfg,
181 struct GNUNET_SERVICE_Handle *sh)
183 struct GNUNET_MQ_MessageHandler ch[] = {
184 GNUNET_MQ_handler_end()
186 struct GNUNET_MQ_Envelope *env;
191 cmq = GNUNET_CLIENT_connect(cfg,
196 GNUNET_SCHEDULER_add_shutdown(&do_shutdown,
198 tt = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_MINUTES,
201 for (unsigned int i = 0; i < NUM_TRANSMISSIONS; i++)
205 cnt = GNUNET_new(unsigned int);
207 env = GNUNET_MQ_msg(m,
208 GNUNET_MESSAGE_TYPE_DUMMY);
209 GNUNET_MQ_notify_sent(env,
216 env = GNUNET_MQ_msg(m,
217 GNUNET_MESSAGE_TYPE_DUMMY2);
224 * Callback to be called when a client connects to the service.
226 * @param cls closure for the service
227 * @param c the new client that connected to the service
228 * @param mq the message queue used to send messages to the client
229 * @return the client-specific (`internal') closure
232 connect_cb(void *cls,
233 struct GNUNET_SERVICE_Client *c,
234 struct GNUNET_MQ_Handle *mq)
243 * Callback to be called when a client disconnected from the service
245 * @param cls closure for the service
246 * @param c the client that disconnected
247 * @param internal_cls the client-specific (`internal') closure
250 disconnect_cb(void *cls,
251 struct GNUNET_SERVICE_Client *c,
263 struct GNUNET_MQ_Envelope *mqm;
264 struct MyMessage *mm;
269 mqm = GNUNET_MQ_msg(mm,
270 GNUNET_MESSAGE_TYPE_DUMMY);
271 GNUNET_assert(NULL != mqm);
272 GNUNET_assert(NULL != mm);
273 GNUNET_assert(GNUNET_MESSAGE_TYPE_DUMMY == ntohs(mm->header.type));
274 GNUNET_assert(sizeof(struct MyMessage) == ntohs(mm->header.size));
275 GNUNET_MQ_discard(mqm);
282 struct GNUNET_MQ_Envelope *mqm;
283 struct GNUNET_MessageHeader *mh;
285 mqm = GNUNET_MQ_msg_header(GNUNET_MESSAGE_TYPE_DUMMY);
286 /* how could the above be checked? */
288 GNUNET_MQ_discard(mqm);
290 mqm = GNUNET_MQ_msg_header_extra(mh,
292 GNUNET_MESSAGE_TYPE_DUMMY);
293 GNUNET_assert(GNUNET_MESSAGE_TYPE_DUMMY == ntohs(mh->type));
294 GNUNET_assert(sizeof(struct GNUNET_MessageHeader) + 20 == ntohs(mh->size));
295 GNUNET_MQ_discard(mqm);
300 main(int argc, char **argv)
302 char * test_argv[] = {
303 (char *)"test_client",
305 "test_client_data.conf",
308 struct GNUNET_MQ_MessageHandler mh[] = {
309 GNUNET_MQ_hd_fixed_size(dummy,
310 GNUNET_MESSAGE_TYPE_DUMMY,
313 GNUNET_MQ_hd_fixed_size(dummy2,
314 GNUNET_MESSAGE_TYPE_DUMMY2,
317 GNUNET_MQ_handler_end()
322 GNUNET_log_setup("test-mq",
328 GNUNET_SERVICE_run_(3,
331 GNUNET_SERVICE_OPTION_NONE,