aboutsummaryrefslogtreecommitdiff
path: root/src/util/test_mq.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/test_mq.c')
-rw-r--r--src/util/test_mq.c294
1 files changed, 274 insertions, 20 deletions
diff --git a/src/util/test_mq.c b/src/util/test_mq.c
index 9e8fc844e..c02ee677e 100644
--- a/src/util/test_mq.c
+++ b/src/util/test_mq.c
@@ -1,30 +1,39 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2012 GNUnet e.V. 3 Copyright (C) 2012, 2018 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
22 * @file util/test_mq.c 20 * @file util/test_mq.c
23 * @brief simple tests for mq 21 * @brief tests for mq
22 * @author Florian Dold
23 * @author Christian Grothoff
24 */ 24 */
25#include "platform.h" 25#include "platform.h"
26#include "gnunet_util_lib.h" 26#include "gnunet_util_lib.h"
27 27
28#define NUM_TRANSMISSIONS 500
29
30/**
31 * How long does the receiver take per message?
32 */
33#define RECEIVER_THROTTLE GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 1)
34
35static unsigned int received_cnt;
36
28 37
29GNUNET_NETWORK_STRUCT_BEGIN 38GNUNET_NETWORK_STRUCT_BEGIN
30 39
@@ -36,6 +45,216 @@ struct MyMessage
36 45
37GNUNET_NETWORK_STRUCT_END 46GNUNET_NETWORK_STRUCT_END
38 47
48static int global_ret;
49
50static struct GNUNET_SCHEDULER_Task *tt;
51
52static struct GNUNET_SCHEDULER_Task *dt;
53
54static struct GNUNET_MQ_Handle *cmq;
55
56
57static void
58do_shutdown (void *cls)
59{
60 (void) cls;
61 if (NULL != tt)
62 {
63 GNUNET_SCHEDULER_cancel (tt);
64 tt = NULL;
65 }
66 if (NULL != cmq)
67 {
68 GNUNET_MQ_destroy (cmq);
69 cmq = NULL;
70 }
71}
72
73
74static void
75do_timeout (void *cls)
76{
77 (void) cls;
78 tt = NULL;
79 GNUNET_SCHEDULER_shutdown ();
80 global_ret = 1;
81}
82
83
84/**
85 * Generic error handler, called with the appropriate
86 * error code and the same closure specified at the creation of
87 * the message queue.
88 * Not every message queue implementation supports an error handler.
89 *
90 * @param cls closure
91 * @param error error code
92 */
93static void
94error_cb (void *cls,
95 enum GNUNET_MQ_Error error)
96{
97 GNUNET_break (0);
98 global_ret = 3;
99 GNUNET_SCHEDULER_shutdown ();
100}
101
102
103static void
104client_continue (void *cls)
105{
106 struct GNUNET_SERVICE_Client *c = cls;
107
108 dt = NULL;
109 GNUNET_SERVICE_client_continue (c);
110}
111
112
113static void
114handle_dummy (void *cls,
115 const struct MyMessage *msg)
116{
117 struct GNUNET_SERVICE_Client *c = cls;
118
119 GNUNET_assert (NULL == dt);
120 /* artificially make receiver slower than sender */
121 dt = GNUNET_SCHEDULER_add_delayed (RECEIVER_THROTTLE,
122 &client_continue,
123 c);
124 if (received_cnt != ntohl (msg->x))
125 {
126 GNUNET_break (0);
127 global_ret = 4;
128 GNUNET_SCHEDULER_shutdown ();
129 }
130 received_cnt++;
131}
132
133
134static void
135handle_dummy2 (void *cls,
136 const struct MyMessage *msg)
137{
138 struct GNUNET_SERVICE_Client *c = cls;
139
140 GNUNET_SERVICE_client_continue (c);
141 if (NUM_TRANSMISSIONS != received_cnt)
142 {
143 GNUNET_break (0);
144 global_ret = 5;
145 }
146 GNUNET_SCHEDULER_shutdown ();
147}
148
149
150/**
151 * Function called whenever MQ has sent a message.
152 */
153static void
154notify_sent_cb (void *cls)
155{
156 static unsigned int seen;
157 unsigned int *cnt = cls;
158
159 if (seen != *cnt)
160 {
161 GNUNET_break (0);
162 global_ret = 6;
163 GNUNET_SCHEDULER_shutdown ();
164 }
165 seen++;
166 GNUNET_free (cnt);
167}
168
169
170/**
171 * Start running the actual test.
172 *
173 * @param cls closure passed to #GNUNET_SERVICE_MAIN
174 * @param cfg configuration to use for this service
175 * @param sh handle to the newly create service
176 */
177static void
178run (void *cls,
179 const struct GNUNET_CONFIGURATION_Handle *cfg,
180 struct GNUNET_SERVICE_Handle *sh)
181{
182 struct GNUNET_MQ_MessageHandler ch[] = {
183 GNUNET_MQ_handler_end ()
184 };
185 struct GNUNET_MQ_Envelope *env;
186 struct MyMessage *m;
187
188 (void) cls;
189 (void) sh;
190 cmq = GNUNET_CLIENT_connect (cfg,
191 "test_client",
192 ch,
193 &error_cb,
194 NULL);
195 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
196 NULL);
197 tt = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
198 &do_timeout,
199 NULL);
200 for (unsigned int i=0;i<NUM_TRANSMISSIONS;i++)
201 {
202 unsigned int *cnt;
203
204 cnt = GNUNET_new (unsigned int);
205 *cnt = i;
206 env = GNUNET_MQ_msg (m,
207 GNUNET_MESSAGE_TYPE_DUMMY);
208 GNUNET_MQ_notify_sent (env,
209 &notify_sent_cb,
210 cnt);
211 m->x = htonl (i);
212 GNUNET_MQ_send (cmq,
213 env);
214 }
215 env = GNUNET_MQ_msg (m,
216 GNUNET_MESSAGE_TYPE_DUMMY2);
217 GNUNET_MQ_send (cmq,
218 env);
219}
220
221
222/**
223 * Callback to be called when a client connects to the service.
224 *
225 * @param cls closure for the service
226 * @param c the new client that connected to the service
227 * @param mq the message queue used to send messages to the client
228 * @return the client-specific (`internal') closure
229 */
230static void *
231connect_cb (void *cls,
232 struct GNUNET_SERVICE_Client *c,
233 struct GNUNET_MQ_Handle *mq)
234{
235 (void) cls;
236 (void) mq;
237 return c;
238}
239
240
241/**
242 * Callback to be called when a client disconnected from the service
243 *
244 * @param cls closure for the service
245 * @param c the client that disconnected
246 * @param internal_cls the client-specific (`internal') closure
247 */
248static void
249disconnect_cb (void *cls,
250 struct GNUNET_SERVICE_Client *c,
251 void *internal_cls)
252{
253 (void) cls;
254 (void) c;
255 (void) internal_cls;
256}
257
39 258
40static void 259static void
41test1 () 260test1 ()
@@ -46,10 +265,11 @@ test1 ()
46 mm = NULL; 265 mm = NULL;
47 mqm = NULL; 266 mqm = NULL;
48 267
49 mqm = GNUNET_MQ_msg (mm, 42); 268 mqm = GNUNET_MQ_msg (mm,
269 GNUNET_MESSAGE_TYPE_DUMMY);
50 GNUNET_assert (NULL != mqm); 270 GNUNET_assert (NULL != mqm);
51 GNUNET_assert (NULL != mm); 271 GNUNET_assert (NULL != mm);
52 GNUNET_assert (42 == ntohs (mm->header.type)); 272 GNUNET_assert (GNUNET_MESSAGE_TYPE_DUMMY == ntohs (mm->header.type));
53 GNUNET_assert (sizeof (struct MyMessage) == ntohs (mm->header.size)); 273 GNUNET_assert (sizeof (struct MyMessage) == ntohs (mm->header.size));
54 GNUNET_MQ_discard (mqm); 274 GNUNET_MQ_discard (mqm);
55} 275}
@@ -61,13 +281,15 @@ test2 ()
61 struct GNUNET_MQ_Envelope *mqm; 281 struct GNUNET_MQ_Envelope *mqm;
62 struct GNUNET_MessageHeader *mh; 282 struct GNUNET_MessageHeader *mh;
63 283
64 mqm = GNUNET_MQ_msg_header (42); 284 mqm = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_DUMMY);
65 /* how could the above be checked? */ 285 /* how could the above be checked? */
66 286
67 GNUNET_MQ_discard (mqm); 287 GNUNET_MQ_discard (mqm);
68 288
69 mqm = GNUNET_MQ_msg_header_extra (mh, 20, 42); 289 mqm = GNUNET_MQ_msg_header_extra (mh,
70 GNUNET_assert (42 == ntohs (mh->type)); 290 20,
291 GNUNET_MESSAGE_TYPE_DUMMY);
292 GNUNET_assert (GNUNET_MESSAGE_TYPE_DUMMY == ntohs (mh->type));
71 GNUNET_assert (sizeof (struct GNUNET_MessageHeader) + 20 == ntohs (mh->size)); 293 GNUNET_assert (sizeof (struct GNUNET_MessageHeader) + 20 == ntohs (mh->size));
72 GNUNET_MQ_discard (mqm); 294 GNUNET_MQ_discard (mqm);
73} 295}
@@ -76,9 +298,41 @@ test2 ()
76int 298int
77main (int argc, char **argv) 299main (int argc, char **argv)
78{ 300{
79 GNUNET_log_setup ("test-mq", "INFO", NULL); 301 char * test_argv[] = {
302 (char *) "test_client",
303 "-c",
304 "test_client_data.conf",
305 NULL
306 };
307 struct GNUNET_MQ_MessageHandler mh[] = {
308 GNUNET_MQ_hd_fixed_size (dummy,
309 GNUNET_MESSAGE_TYPE_DUMMY,
310 struct MyMessage,
311 NULL),
312 GNUNET_MQ_hd_fixed_size (dummy2,
313 GNUNET_MESSAGE_TYPE_DUMMY2,
314 struct MyMessage,
315 NULL),
316 GNUNET_MQ_handler_end ()
317 };
318
319 (void) argc;
320 (void) argv;
321 GNUNET_log_setup ("test-mq",
322 "INFO",
323 NULL);
80 test1 (); 324 test1 ();
81 test2 (); 325 test2 ();
82 return 0; 326 if (0 !=
327 GNUNET_SERVICE_run_ (3,
328 test_argv,
329 "test_client",
330 GNUNET_SERVICE_OPTION_NONE,
331 &run,
332 &connect_cb,
333 &disconnect_cb,
334 NULL,
335 mh))
336 return 1;
337 return global_ret;
83} 338}
84