aboutsummaryrefslogtreecommitdiff
path: root/src/messenger/testing_messenger_setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/messenger/testing_messenger_setup.c')
-rw-r--r--src/messenger/testing_messenger_setup.c547
1 files changed, 0 insertions, 547 deletions
diff --git a/src/messenger/testing_messenger_setup.c b/src/messenger/testing_messenger_setup.c
deleted file mode 100644
index 3cde8c9bb..000000000
--- a/src/messenger/testing_messenger_setup.c
+++ /dev/null
@@ -1,547 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2020--2021 GNUnet e.V.
4
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.
9
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.
14
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/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @file messenger/testing_messenger_barrier.c
22 * @author Tobias Frisch
23 * @brief A simple test-case setup for the messenger service
24 */
25
26#include "testing_messenger_setup.h"
27
28#include <stdio.h>
29#include "platform.h"
30#include "gnunet_util_lib.h"
31#include "gnunet_testbed_logger_service.h"
32#include "gnunet_testbed_service.h"
33#include "gnunet_testing_lib.h"
34#include "gnunet_messenger_service.h"
35#include "testing_messenger_barrier.h"
36
37#define TEST_ROOM "test"
38#define TEST_NAME "tester"
39
40struct test_properties;
41
42struct test_peer {
43 struct test_properties *props;
44 unsigned int num;
45
46 struct GNUNET_SCHEDULER_Task *op_task;
47 struct GNUNET_TESTBED_Operation *op;
48
49 struct GNUNET_TESTBED_Peer *peer;
50 struct GNUNET_PeerIdentity peer_id;
51 struct GNUNET_BarrierWaitHandle *wait;
52
53 struct GNUNET_MESSENGER_Handle *handle;
54 struct GNUNET_MESSENGER_Room *room;
55
56 unsigned int peer_messages;
57
58 const char *message;
59};
60
61struct test_properties {
62 const struct test_configuration *cfg;
63
64 unsigned int num_hosts;
65
66 struct GNUNET_SCHEDULER_Task *die_task;
67 struct GNUNET_SCHEDULER_Task *end_task;
68
69 struct GNUNET_BarrierHandle *barrier;
70
71 struct test_peer *peers;
72 unsigned int num_peer;
73
74 int status;
75};
76
77static void
78shutdown_cb (void *cls)
79{
80 struct test_properties *properties = cls;
81
82
83 for (unsigned int i = 0; i < properties->num_peer; i++)
84 {
85 struct test_peer *peer = &properties->peers[i];
86
87 GNUNET_assert(peer != NULL);
88
89 if (peer->op_task)
90 GNUNET_SCHEDULER_cancel(peer->op_task);
91
92 peer->op_task = NULL;
93
94 if (peer->op)
95 GNUNET_TESTBED_operation_done (peer->op);
96
97 peer->op = NULL;
98
99 if (peer->wait)
100 GNUNET_cancel_wait_barrier(peer->wait);
101
102 peer->wait = NULL;
103
104 if (peer->room)
105 GNUNET_MESSENGER_close_room (peer->room);
106
107 peer->room = NULL;
108
109 if (peer->handle)
110 GNUNET_MESSENGER_disconnect (peer->handle);
111
112 peer->handle = NULL;
113 }
114
115 if (properties->die_task)
116 GNUNET_SCHEDULER_cancel(properties->die_task);
117
118 properties->die_task = NULL;
119 properties->end_task = NULL;
120
121 if (properties->barrier)
122 GNUNET_cancel_barrier(properties->barrier);
123
124 properties->barrier = NULL;
125}
126
127
128
129static void
130end_cb (void *cls)
131{
132 struct test_properties *properties = cls;
133
134 GNUNET_assert(properties != NULL);
135
136 properties->die_task = NULL;
137
138 int status = 0;
139
140 for (unsigned int i = 0; i < properties->num_peer; i++)
141 {
142 struct test_peer *peer = &properties->peers[i];
143
144 GNUNET_assert(peer != NULL);
145
146 const int members = GNUNET_MESSENGER_iterate_members(peer->room, NULL, NULL);
147
148 GNUNET_assert (members >= 0);
149
150 if (peer->props->num_peer != (unsigned int) members)
151 {
152 fprintf (stderr, "Testcase failed (members: %d/%u).\n", members, peer->props->num_peer);
153 status = 1;
154 break;
155 }
156 }
157
158 GNUNET_SCHEDULER_shutdown ();
159
160 properties->status = status;
161}
162
163static void
164end_badly_cb (void *cls)
165{
166 struct test_properties *properties = cls;
167
168 GNUNET_assert(properties != NULL);
169
170 fprintf (stderr, "Testcase failed (timeout).\n");
171
172 end_cb (properties);
173
174 properties->status = 1;
175}
176
177static void
178end_operation_cb (void *cls)
179{
180 struct test_peer *peer = cls;
181
182 GNUNET_assert(peer != NULL);
183
184 peer->op_task = NULL;
185
186 fprintf (stderr, "Testcase failed (operation: '%s').\n", peer->message);
187
188 GNUNET_SCHEDULER_shutdown ();
189}
190
191static void
192end_error_cb (void *cls)
193{
194 struct test_peer *peer = cls;
195
196 GNUNET_assert(peer != NULL);
197
198 peer->op_task = NULL;
199
200 fprintf (stderr, "Testcase failed (error: '%s').\n", peer->message);
201 GNUNET_free (peer);
202
203 GNUNET_SCHEDULER_shutdown ();
204}
205
206static void
207barrier2_wait_cb (void *cls,
208 struct GNUNET_BarrierWaitHandle *waiting,
209 int status)
210{
211 struct test_peer *peer = cls;
212
213 GNUNET_assert(peer != NULL);
214
215 if (peer->wait == waiting)
216 peer->wait = NULL;
217}
218
219static void
220barrier_wait_cb (void *cls,
221 struct GNUNET_BarrierWaitHandle *waiting,
222 int status)
223{
224 struct test_peer *peer = cls;
225
226 GNUNET_assert(peer != NULL);
227
228 if (peer->wait == waiting)
229 peer->wait = NULL;
230
231 if (0 != (peer->props->cfg->stages[peer->num - 1] & 0x02))
232 {
233 unsigned int door = peer->props->cfg->doors[peer->num - 1];
234
235 if (door == 0)
236 door = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, peer->props->cfg->count);
237 else
238 door = door - 1;
239
240 struct GNUNET_HashCode hash;
241 GNUNET_CRYPTO_hash (TEST_ROOM, sizeof(TEST_ROOM), &hash);
242
243 struct GNUNET_MESSENGER_Room *room;
244 room = GNUNET_MESSENGER_enter_room(peer->handle, &(peer->props->peers[door].peer_id), &hash);
245
246 if (peer->room)
247 GNUNET_assert(room == peer->room);
248 else
249 GNUNET_assert(room != NULL);
250
251 peer->room = room;
252 }
253}
254
255/**
256 * Function called whenever a message is received or sent.
257 *
258 * @param cls Closure
259 * @param room Room
260 * @param sender Sender
261 * @param message Message
262 * @param hash Hash of message
263 * @param flags Flags of message
264 */
265static void
266on_message (void *cls,
267 struct GNUNET_MESSENGER_Room *room,
268 const struct GNUNET_MESSENGER_Contact *sender,
269 const struct GNUNET_MESSENGER_Message *message,
270 const struct GNUNET_HashCode *hash,
271 enum GNUNET_MESSENGER_MessageFlags flags)
272{
273 struct test_peer *peer = cls;
274
275 GNUNET_assert(peer != NULL);
276
277 fprintf (stderr, "Peer: %s; [%s] Message: %s (%s)\n",
278 GNUNET_i2s(&(peer->peer_id)),
279 GNUNET_sh2s(&(message->header.sender_id)),
280 GNUNET_MESSENGER_name_of_kind(message->header.kind),
281 GNUNET_h2s(hash));
282
283 if (GNUNET_MESSENGER_KIND_PEER == message->header.kind)
284 peer->peer_messages++;
285
286 if (peer->props->num_hosts == peer->peer_messages)
287 peer->wait = GNUNET_wait_barrier (peer->props->barrier, &barrier2_wait_cb, peer);
288 else if (peer->props->num_hosts < peer->peer_messages)
289 {
290 if (peer->wait)
291 GNUNET_cancel_wait_barrier(peer->wait);
292
293 peer->wait = NULL;
294
295 if (peer->op_task)
296 GNUNET_SCHEDULER_cancel(peer->op_task);
297
298 peer->message = "peer";
299 peer->op_task = GNUNET_SCHEDULER_add_now (&end_operation_cb, peer);
300 }
301}
302
303static void
304second_stage (void *cls)
305{
306 struct test_peer *peer = cls;
307
308 GNUNET_assert(peer != NULL);
309
310 peer->op_task = NULL;
311
312 struct GNUNET_HashCode hash;
313 GNUNET_CRYPTO_hash (TEST_ROOM, sizeof(TEST_ROOM), &hash);
314
315 if (0 != (peer->props->cfg->stages[peer->num - 1] & 0x10))
316 {
317 struct GNUNET_MESSENGER_Room *room;
318 room = GNUNET_MESSENGER_open_room (peer->handle, &hash);
319
320 if (peer->room)
321 GNUNET_assert(room == peer->room);
322 else
323 GNUNET_assert(room != NULL);
324
325 peer->room = room;
326 }
327
328 if (0 != (peer->props->cfg->stages[peer->num - 1] & 0x20))
329 {
330 unsigned int door = peer->props->cfg->doors[peer->num - 1];
331
332 if (door == 0)
333 door = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, peer->props->cfg->count);
334 else
335 door = door - 1;
336
337 struct GNUNET_MESSENGER_Room *room;
338 room = GNUNET_MESSENGER_enter_room(peer->handle, &(peer->props->peers[door].peer_id), &hash);
339
340 if (peer->room)
341 GNUNET_assert(room == peer->room);
342 else
343 GNUNET_assert(room != NULL);
344
345 peer->room = room;
346 }
347}
348
349static void
350on_peer (void *cb_cls,
351 struct GNUNET_TESTBED_Operation *op,
352 const struct GNUNET_TESTBED_PeerInformation *pinfo,
353 const char *emsg)
354{
355 struct test_peer *peer = cb_cls;
356
357 GNUNET_assert(peer != NULL);
358
359 if (emsg)
360 {
361 peer->message = GNUNET_strdup(emsg);
362 peer->op_task = GNUNET_SCHEDULER_add_now (&end_error_cb, peer);
363 return;
364 }
365
366 if (!pinfo)
367 {
368 peer->message = "info";
369 peer->op_task = GNUNET_SCHEDULER_add_now (&end_operation_cb, peer);
370 return;
371 }
372
373 if (pinfo->pit != GNUNET_TESTBED_PIT_CONFIGURATION)
374 {
375 peer->message = "config";
376 peer->op_task = GNUNET_SCHEDULER_add_now (&end_operation_cb, peer);
377 return;
378 }
379
380 peer->handle = GNUNET_MESSENGER_connect (pinfo->result.cfg, TEST_NAME, NULL, NULL, &on_message, peer);
381
382 GNUNET_assert(GNUNET_OK == GNUNET_CRYPTO_get_peer_identity(
383 pinfo->result.cfg, &(peer->peer_id)
384 ));
385
386 if (0 != (peer->props->cfg->stages[peer->num - 1] & 0x01))
387 {
388 struct GNUNET_HashCode hash;
389 GNUNET_CRYPTO_hash (TEST_ROOM, sizeof(TEST_ROOM), &hash);
390
391 peer->room = GNUNET_MESSENGER_open_room (peer->handle, &hash);
392
393 GNUNET_assert(peer->room != NULL);
394 }
395 else
396 peer->room = NULL;
397
398 peer->wait = GNUNET_wait_barrier (peer->props->barrier, &barrier_wait_cb, peer);
399}
400
401/**
402 * Main function for a peer of the testcase.
403 *
404 * @param cls Closure
405 * @param event Information about the event
406 */
407static void
408run (void *cls,
409 const struct GNUNET_TESTBED_EventInformation *event)
410{
411 struct test_properties *properties = cls;
412
413 GNUNET_assert(properties != NULL);
414
415 if (GNUNET_TESTBED_ET_PEER_START != event->type)
416 {
417 fprintf (stderr, "Testcase failed (operation: 'start').\n");
418
419 GNUNET_SCHEDULER_shutdown ();
420 return;
421 }
422
423 struct test_peer *peer = &(properties->peers[properties->num_peer++]);
424
425 peer->props = properties;
426 peer->num = properties->num_peer;
427
428 peer->peer = event->details.peer_start.peer;
429 peer->op = GNUNET_TESTBED_peer_get_information (peer->peer, GNUNET_TESTBED_PIT_CONFIGURATION, on_peer, peer);
430}
431
432static void
433barrier2_cb (void *cls,
434 struct GNUNET_BarrierHandle *barrier,
435 int status)
436{
437 struct test_properties *properties = cls;
438
439 GNUNET_assert(properties != NULL);
440
441 if (properties->barrier == barrier)
442 properties->barrier = NULL;
443
444 if (GNUNET_SYSERR == status)
445 {
446 fprintf (stderr, "Testcase failed (operation: 'barrier2').\n");
447
448 GNUNET_SCHEDULER_shutdown ();
449 return;
450 }
451 else if (GNUNET_OK == status)
452 {
453 if (properties->die_task)
454 GNUNET_SCHEDULER_cancel(properties->die_task);
455
456 properties->die_task = GNUNET_SCHEDULER_add_delayed (
457 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, properties->cfg->count),
458 &end_cb, properties
459 );
460 }
461}
462
463static void
464barrier_cb (void *cls,
465 struct GNUNET_BarrierHandle *barrier,
466 int status)
467{
468 struct test_properties *properties = cls;
469
470 GNUNET_assert(properties != NULL);
471
472 if (properties->barrier == barrier)
473 properties->barrier = NULL;
474 else if (!properties->barrier)
475 return;
476
477 if (properties->num_peer != properties->cfg->count)
478 {
479 fprintf (stderr, "Testcase failed (operation: 'process').\n");
480
481 GNUNET_SCHEDULER_shutdown ();
482 return;
483 }
484
485 if (GNUNET_SYSERR == status)
486 {
487 fprintf (stderr, "Testcase failed (operation: 'barrier').\n");
488
489 GNUNET_SCHEDULER_shutdown ();
490 return;
491 }
492 else if (GNUNET_OK == status)
493 {
494 properties->barrier = GNUNET_init_barrier (properties->num_peer, &barrier2_cb, properties);
495
496 for (unsigned int i = 0; i < properties->num_peer; i++)
497 properties->peers[i].op_task = GNUNET_SCHEDULER_add_now (&second_stage, &(properties->peers[i]));
498 }
499}
500
501static void
502init (void *cls,
503 struct GNUNET_TESTBED_RunHandle *h,
504 unsigned int num_peers,
505 struct GNUNET_TESTBED_Peer **peers,
506 unsigned int links_succeeded,
507 unsigned int links_failed)
508{
509 struct test_properties *properties = cls;
510
511 GNUNET_assert(properties != NULL);
512
513 properties->end_task = GNUNET_SCHEDULER_add_shutdown(&shutdown_cb, properties);
514 properties->die_task = GNUNET_SCHEDULER_add_delayed (
515 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, properties->cfg->count * 5),
516 &end_badly_cb, properties
517 );
518}
519
520int
521GNUNET_run_messenger_setup (const char* test_name,
522 const struct test_configuration *cfg)
523{
524 struct test_properties properties;
525 memset(&properties, 0, sizeof(properties));
526
527 properties.cfg = cfg;
528 properties.peers = GNUNET_new_array(cfg->count, struct test_peer);
529
530 for (unsigned int i = 0; i < cfg->count; i++)
531 if (0 != (cfg->stages[i] & 0x11))
532 properties.num_hosts++;
533
534 properties.status = 1;
535 properties.barrier = GNUNET_init_barrier (cfg->count, &barrier_cb, &properties);
536
537 if (GNUNET_OK != GNUNET_TESTBED_test_run (test_name, "test_messenger_api.conf",
538 cfg->count,
539 (1LL << GNUNET_TESTBED_ET_PEER_START),
540 &run, &properties,
541 &init, &properties))
542 return 1;
543
544 GNUNET_free(properties.peers);
545
546 return properties.status;
547}